From 677f91fdcef832a100ec2560b910f7786fcb9922 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 7 Apr 2019 20:53:30 -0400 Subject: [PATCH] Updates Part Four --- code/game/gamemodes/epidemic/epidemic.dm | 19 +- .../game/machinery/computer/communications.dm | 7 + code/modules/admin/verbs/randomverbs.dm | 12 +- .../modules/modular_computers/_description.dm | 21 +- .../computers/item/modular_computer.dm | 21 +- .../{item => machinery}/console_presets.dm | 2 + .../computers/machinery/modular_computer.dm | 3 + .../modular_computers/file_system/program.dm | 9 +- .../file_system/programs/_program.dm | 11 + .../file_system/programs/antagonist/dos.dm | 12 +- .../programs/antagonist/revelation.dm | 8 +- .../file_system/programs/card.dm | 52 +-- .../file_system/programs/comm.dm | 310 ++++++++++++++++++ .../file_system/programs/configurator.dm | 10 +- .../file_system/programs/file_browser.dm | 78 +++-- .../file_system/programs/ntdownloader.dm | 13 +- .../file_system/programs/ntmonitor.dm | 21 +- .../file_system/programs/ntnrc_client.dm | 48 ++- .../file_system/programs/nttransfer.dm | 19 +- code/modules/nano/modules/alarm_monitor.dm | 7 +- code/modules/nano/modules/atmos_control.dm | 7 +- code/modules/nano/modules/crew_monitor.dm | 4 +- code/modules/nano/modules/human_appearance.dm | 2 +- code/modules/nano/modules/nano_module.dm | 24 +- code/modules/nano/modules/power_monitor.dm | 6 +- code/modules/nano/modules/rcon.dm | 6 +- nano/templates/mod_communication.tmpl | 66 ++++ ....tmpl => mod_identification_computer.tmpl} | 0 polaris.dme | 2 + 29 files changed, 614 insertions(+), 186 deletions(-) rename code/modules/modular_computers/computers/{item => machinery}/console_presets.dm (97%) create mode 100644 code/modules/modular_computers/file_system/programs/_program.dm create mode 100644 code/modules/modular_computers/file_system/programs/comm.dm create mode 100644 nano/templates/mod_communication.tmpl rename nano/templates/{identification_computer_lap.tmpl => mod_identification_computer.tmpl} (100%) diff --git a/code/game/gamemodes/epidemic/epidemic.dm b/code/game/gamemodes/epidemic/epidemic.dm index b6e4146a9c..e6b4f9d456 100644 --- a/code/game/gamemodes/epidemic/epidemic.dm +++ b/code/game/gamemodes/epidemic/epidemic.dm @@ -46,14 +46,8 @@ intercepttext += "* A cure is to be researched immediately, but NanoTrasen intellectual property must be respected. To prevent knowledge of [virus_name] from falling into unauthorized hands, all medical staff that work with the pathogen must be enhanced with a NanoTrasen loyality implant.
" - for (var/obj/machinery/computer/communications/comm in world) - if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) - var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper" - intercept.info = intercepttext - - comm.messagetitle.Add("CentCom CONFIDENTIAL REPORT") - comm.messagetext.Add(intercepttext) + //New message handling won't hurt if someone enables epidemic + post_comm_message("Cent. Com. CONFIDENTIAL REPORT", intercepttext) world << sound('sound/AI/commandreport.ogg') @@ -68,14 +62,7 @@ intercepttext += "PATHOGEN [virus_name] IS STILL PRESENT ON [station_name()]. IN COMPLIANCE WITH NANOTRASEN LAWS FOR INTERSTELLAR SAFETY, EMERGENCY SAFETY MEASURES HAVE BEEN AUTHORIZED. ALL INFECTED CREW MEMBERS ON [station_name()] ARE TO BE NEUTRALIZED AND DISPOSED OF IN A MANNER THAT WILL DESTROY ALL TRACES OF THE PATHOGEN. FAILURE TO COMPLY WILL RESULT IN IMMEDIATE DESTRUCTION OF [station_name].
" intercepttext += "CRUISER WILL ARRIVE IN [round(cruiser_seconds()/60)] MINUTES
" - for (var/obj/machinery/computer/communications/comm in world) - if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) - var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "paper" - intercept.info = intercepttext - - comm.messagetitle.Add("CentCom CONFIDENTIAL REPORT") - comm.messagetext.Add(intercepttext) + post_comm_message("Cent. Com. CONFIDENTIAL REPORT", intercepttext) world << sound('sound/AI/commandreport.ogg') diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 68093398c8..97a3cfed95 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -529,6 +529,13 @@ message_admins("[key_name_admin(user)] has recalled the shuttle.", 1) return + +/proc/is_relay_online() + for(var/obj/machinery/telecomms/relay/M in world) + if(M.stat == 0) + return 1 + return 0 + /obj/machinery/computer/communications/proc/post_status(var/command, var/data1, var/data2) var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 3f7908c1a8..0e043188b6 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -565,15 +565,9 @@ Traitors and the like can also be revived with the previous role mostly intact. return if(!customname) customname = "[using_map.company_name] Update" - for (var/obj/machinery/computer/communications/C in machines) - if(! (C.stat & (BROKEN|NOPOWER) ) ) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc ) - P.name = "'[command_name()] Update.'" - P.info = replacetext(input, "\n", "
") - P.update_space(P.info) - P.update_icon() - C.messagetitle.Add("[command_name()] Update") - C.messagetext.Add(P.info) + + //New message handling + post_comm_message(customname, replacetext(input, "\n", "
")) switch(alert("Should this be announced to the general population?",,"Yes","No")) if("Yes") diff --git a/code/modules/modular_computers/_description.dm b/code/modules/modular_computers/_description.dm index a9ea30757b..2335ce08e7 100644 --- a/code/modules/modular_computers/_description.dm +++ b/code/modules/modular_computers/_description.dm @@ -1,5 +1,7 @@ /* Program-based computers, designed to replace computer3 project and eventually most consoles on station + + 1. Basic information Program based computers will allow you to do multiple things from single computer. Each computer will have programs, with more being downloadable from NTNet (stationwide network with wireless coverage) if user has apropriate ID card access. It will be possible to hack the computer by using an emag on it - the emag will have to be completely new and will be consumed on use, but it will @@ -7,6 +9,7 @@ lift ALL locks on ALL installed programs, and allow download of programs even if Files can be programs (datum/computer_file/program/ subtype) or data files (datum/computer_file/data/ subtypes). Program for sending files will be available that will allow transfer via NTNet. NTNet coverage will be limited to station's Z level, but better network card (=more expensive and higher power use) will allow usage everywhere. Hard drives will have limited capacity for files which will be related to how good hard drive you buy when purchasing the laptop. For storing more files USB-style drives will be buildable with Protolathe in research. + 2. Available devices CONSOLES Consoles will come in various pre-fabricated loadouts, each loadout starting with certain set of programs (aka Engineering console, Medical console, etc.), of course, more software may be downloaded. @@ -21,6 +24,8 @@ TABLETS Tablets are smallest available devices, designed with full mobility in mind. Tablets have only weak CPU which means the software they can run is somewhat limited. They are also designed with high battery life in mind, which means the hardware focuses on power efficiency rather than high performance. This is most visible with hard drives which have quite small storage capacity. Tablets can't be equipped with tesla link, which means they have to be recharged manually. + + 3. Computer Hardware Computers will come with basic hardware installed, with upgrades being selectable when purchasing the device. Hard Drive: Stores data, mandatory for the computer to work @@ -31,17 +36,21 @@ ID Card Slot: Required for HoP-style programs to work. Access for security recor APC Tesla Relay: Wirelessly powers the device from APC. Consoles have it by default. Laptops can buy it. Disk Drive: Allows usage of portable data disks. Nano Printer: Allows the computer to scan paper contents and save them to file, as well as recycle papers and print stuff on it. + 4. NTNet NTNet is stationwide network that allows users to download programs needed for their work. It will be possible to send any files to other active computers using relevant program (NTN Transfer). NTNet is under jurisdiction of both Engineering and Research. Engineering is responsible for any repairs if necessary and research is responsible for monitoring. It is similar to PDA messaging. Operation requires functional "NTNet Relay" which is by default placed on tcommsat. If the relay is damaged NTNet will be offline until it is replaced. Multiple relays bring extra redundancy, if one is destroyed the second will take over. If all relays are gone it stops working, simple as that. NTNet may be altered via administration console available to Research Director. It is possible to enable/disable Software Downloading, P2P file transfers and Communication (IC version of IRC, PDA messages for more than two people) + 5. Software Software would almost exclusively use NanoUI modules. Few exceptions are text editor (uses similar screen as TCS IDE used for editing and classic HTML for previewing as Nano looks differently) and similar programs which for some reason require HTML UI. Most software will be highly dependent on NTNet to work as laptops are not physically connected to the station's network. What i plan to add: + Note: XXXXDB programs will use ingame_manuals to display basic help for players, similar to how books, etc. do + Basic - Software in this bundle is automagically preinstalled in every new computer NTN Transfer - Allows P2P transfer of files to other computers that run this. Configurator - Allows configuration of computer's hardware, basically status screen. @@ -50,32 +59,38 @@ Basic - Software in this bundle is automagically preinstalled in every new compu NanoPrint - Allows you to operate NanoPrinter hardware to print text files. NTNRC Chat - NTNet Relay Chat client. Allows PDA-messaging style messaging for more than two users. Person which created the conversation is Host and has administrative privilegies (kicking, etc.) NTNet News - Allows reading news from newscaster network. + Engineering - Requires "Engineering" access on ID card (ie. CE, Atmostech, Engineer) Alarm Monitor - Allows monitoring alarms, same as the stationbound one. Power Monitor - Power monitoring computer, connects to sensors in same way as regular one does. Atmospheric Control - Allows access to the Atmospherics Monitor Console that operates air alarms. Requires extra access: "Atmospherics" RCON Remote Control Console - Allows access to the RCON Remote Control Console. Requires extra access: "Power Equipment" EngiDB - Allows accessing NTNet information repository for information about engineering-related things. + Medical - Requires "Medbay" access on ID card (ie. CMO, Doctor,..) Medical Records Uplink - Allows editing/reading of medical records. Printing requires NanoPrinter hardware. MediDB - Allows accessing NTNet information repository for information about medical procedures ChemDB - Requires extra access: "Chemistry" - Downloads basic information about recipes from NTNet + Research - Requires "Research and Development" access on ID card (ie. RD, Roboticist, etc.) Research Server Monitor - Allows monitoring of research levels on RnD servers. (read only) Robotics Monitor Console - Allows monitoring of robots and exosuits. Lockdown/Self-Destruct options are unavailable [balance reasons for malf/traitor AIs]. Requires extra access: "Robotics" NTNRC Administration Console - Allows administrative access to NTNRC. This includes bypassing any channel passwords and enabling "invisible" mode for spying on conversations. Requires extra access: "Research Director" NTNet Administration Console - Allows remote configuration of NTNet Relay - CAUTION: If NTNet is turned off it won't be possible to turn it on again from the computer, as operation requires NTNet to work! Requires extra access: "Research Director" NTNet Monitor - Allows monitoring of NTNet and it's various components, including simplified network logs and system status. + Security - Requires "Security" access on ID card (ie. HOS, Security officer, Detective) Security Records Uplink - Allows editing/reading of security records. Printing requires Nanoprinter hardware. LawDB - Allows accessing NTNet information repository for security information (corporate regulations) Camera Uplink - Allows viewing cameras around the station. + Command - Requires "Bridge" access on ID card (all heads) Alertcon Access - Allows changing of alert levels. Red requires activation from two computers with two IDs similar to how those wall mounted devices do. Employment Records Access - Allows reading of employment records. Printing requires NanoPrinter hardware. Communication Console - Allows sending emergency messages to Central. Emergency Shuttle Control Console - Allows calling/recalling the emergency shuttle. Shuttle Control Console - Allows control of various shuttles around the station (mining, research, engineering) + *REDACTED* - Can be downloaded from SyndiCorp servers, only via emagged devices. These files are very large and limited to laptops/consoles only. SYSCRACK - Allows cracking of secure network terminals, such as, NTNet administration. The sysadmin will probably notice this. SYSOVERRIDE - Allows hacking into any device connected to NTNet. User will notice this and may stop the hack by disconnecting from NTNet first. After hacking various options exist, such as stealing/deleting files. @@ -83,20 +98,24 @@ Command - Requires "Bridge" access on ID card (all heads) SYSDOS - Launches a Denial of Service attack on NTNet relay. Can DoS only one relay at once. Requires NTNet connection. After some time the relay crashes until attack stops. The sysadmin will probably notice this. AIHACK - Hacks an AI, allowing you to upload/remove/modify a law even without relevant circuit board. The AI is alerted once the hack starts, and it takes a while for it to complete. Does not work on AIs with zeroth law. COREPURGE - Deletes all files on the hard drive, including the undeletable ones. Something like software self-destruct for computer. + 6. Security Laptops will be password-lockable. If password is set a MD5 hash of it is stored and password is required every time you turn on the laptop. Passwords may be decrypted by using special Decrypter (protolathable, RDs office starts with one) device that will slowly decrypt the password. Decryption time would be length_of_password * 30 seconds, with maximum being 9 minutes (due to battery life limitations, which is 10+ min). If decrypted the password is cleared, so you can keep using your favorite password without people ever actually revealing it (for meta prevention reasons mostly). Emagged laptops will have option to enable "Safe Encryption". If safely encrypted laptop is decrypted it loses it's emag status and 50% of files is deleted (randomly selected). + 7. System Administrator System Administrator will be new job under Research. It's main specifics will be maintaining of computer systems on station, espicially from software side. From IC perspective they'd probably know how to build a console or something given they work with computers, but they are mostly programmers/network experts. They will have office in research, which will probably replace (and contain) the server room and part of the toxins storage which is currently oversized. They will have access to DOWNLOAD (not run) all programs that exist on NTNet. They'll have fairly good amount of available programs, most of them being administrative consoles and other very useful things. They'll also be able to monitor NTNet. There will probably be one or two job slots. + 8. IDS With addition of various antag programs, IDS(Intrusion Detection System) will be added to NTNet. This system can be turned on/off via administration console. If enabled, this system automatically detects any abnormality and triggers a warning that's visible on the NTNet status screen, as well as generating a security log. IDS can be disabled by simple on/off switch in the configuration. -*/ \ No newline at end of file + +*/ \ No newline at end of file diff --git a/code/modules/modular_computers/computers/item/modular_computer.dm b/code/modules/modular_computers/computers/item/modular_computer.dm index d7cbee5820..bc041adbd5 100644 --- a/code/modules/modular_computers/computers/item/modular_computer.dm +++ b/code/modules/modular_computers/computers/item/modular_computer.dm @@ -71,17 +71,17 @@ user << "There is no card in \the [src]" return - card_slot.stored_card.forceMove(get_turf(src)) - card_slot.stored_card = null - update_uis() - user << "You remove the card from \the [src]" - if(active_program) active_program.event_idremoved(0) for(var/datum/computer_file/program/P in idle_threads) P.event_idremoved(1) + card_slot.stored_card.forceMove(get_turf(src)) + card_slot.stored_card = null + update_uis() + user << "You remove the card from \the [src]" + /obj/item/modular_computer/attack_ghost(var/mob/observer/dead/user) if(enabled) ui_interact(user) @@ -102,14 +102,14 @@ /obj/item/modular_computer/New() START_PROCESSING(SSobj, src) update_icon() - return ..() + ..() /obj/item/modular_computer/Destroy() kill_program(1) STOP_PROCESSING(SSobj, src) for(var/obj/item/weapon/computer_hardware/CH in src.get_all_components()) qdel(CH) - ..() + return ..() /obj/item/modular_computer/update_icon() icon_state = icon_state_unpowered @@ -318,12 +318,12 @@ var/obj/item/weapon/computer_hardware/H = find_hardware_by_name(href_list["PC_enable_component"]) if(H && istype(H) && !H.enabled) H.enabled = 1 - return 1 + . = 1 if( href_list["PC_disable_component"] ) var/obj/item/weapon/computer_hardware/H = find_hardware_by_name(href_list["PC_disable_component"]) if(H && istype(H) && H.enabled) H.enabled = 0 - return 1 + . = 1 if( href_list["PC_shutdown"] ) shutdown_computer() return 1 @@ -374,6 +374,8 @@ active_program = P update_icon() return 1 + if(.) + update_uis() // Used in following function to reduce copypaste /obj/item/modular_computer/proc/power_failure() @@ -392,6 +394,7 @@ return 0 var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage + for(var/obj/item/weapon/computer_hardware/H in get_all_components()) if(H.enabled) power_usage += H.power_usage diff --git a/code/modules/modular_computers/computers/item/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm similarity index 97% rename from code/modules/modular_computers/computers/item/console_presets.dm rename to code/modules/modular_computers/computers/machinery/console_presets.dm index 4c7eb7b0d1..5e9e7f4987 100644 --- a/code/modules/modular_computers/computers/item/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -58,10 +58,12 @@ console_department = "Command" desc = "A stationary computer. This one comes preloaded with command programs." _has_id_slot = 1 + _has_printer = 1 /obj/machinery/modular_computer/console/preset/command/install_programs() cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient()) cpu.hard_drive.store_file(new/datum/computer_file/program/card_mod()) + cpu.hard_drive.store_file(new/datum/computer_file/program/comm()) // ===== SECURITY CONSOLE ===== diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 35a24d321f..21f040074e 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -17,6 +17,7 @@ icon_state = null var/icon_state_unpowered = null // Icon state when the computer is turned off var/screen_icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen. + var/screen_icon_screensaver = "standby" // Icon state overlay when the computer is powered, but not 'switched on'. var/max_hardware_size = 0 // Maximal hardware size. Currently, tablets have 1, laptops 2 and consoles 3. Limits what hardware types can be installed. var/steel_sheet_cost = 10 // Amount of steel sheets refunded when disassembling an empty frame of this computer. @@ -39,6 +40,8 @@ overlays.Cut() if(!cpu || !cpu.enabled) + if (!(stat & NOPOWER) || battery_powered) + overlays.Add(screen_icon_screensaver) return if(cpu.active_program) overlays.Add(cpu.active_program.program_icon_state ? cpu.active_program.program_icon_state : screen_icon_state_menu) diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 0ab40df336..4e09cac65c 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -20,7 +20,6 @@ var/computer_emagged = 0 // Set to 1 if computer that's running us was emagged. Computer updates this every Process() tick var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /nano/images/status_icons. Be careful not to use too large images! - /datum/computer_file/program/New(var/obj/item/modular_computer/comp = null) ..() if(comp && istype(comp)) @@ -55,6 +54,11 @@ return 0 return 1 +/datum/computer_file/program/proc/get_signal(var/specific_action = 0) + if(computer) + return computer.get_ntnet_status(specific_action) + return 0 + // Called by Process() on device that runs us, once every tick. /datum/computer_file/program/proc/process_tick() return 1 @@ -92,8 +96,7 @@ /datum/computer_file/program/proc/run_program(var/mob/living/user) if(can_run(user, 1)) if(nanomodule_path) - NM = new nanomodule_path(computer) // Computer is passed here as it's (probably!) physical object. Some UI's perform get_turf() and passing program datum wouldn't go well with this. - NM.program = src // Set the program reference to separate variable, instead. + NM = new nanomodule_path(computer, src) // Computer is passed here as it's (probably!) physical object. Some UI's perform get_turf() and passing program datum wouldn't go well with this. if(requires_ntnet && network_destination) generate_network_log("Connection opened to [network_destination].") program_state = PROGRAM_STATE_ACTIVE diff --git a/code/modules/modular_computers/file_system/programs/_program.dm b/code/modules/modular_computers/file_system/programs/_program.dm new file mode 100644 index 0000000000..73f0ac95a3 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/_program.dm @@ -0,0 +1,11 @@ +/obj/machinery/modular_computer/initial_data() + return cpu ? cpu.get_header_data() : ..() + +/obj/machinery/modular_computer/update_layout() + return TRUE + +/obj/item/modular_computer/update_layout() + return TRUE + +///datum/nano_module/program + //adheres_to_NT_standard = FALSE diff --git a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm index 440b6d529e..2f21771147 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm @@ -7,7 +7,7 @@ requires_ntnet = 1 available_on_ntnet = 0 available_on_syndinet = 1 - nanomodule_path = /datum/nano_module/computer_dos/ + nanomodule_path = /datum/nano_module/program/computer_dos/ var/obj/machinery/ntnet_relay/target = null var/dos_speed = 0 var/error = "" @@ -36,10 +36,10 @@ ..(forced) -/datum/nano_module/computer_dos +/datum/nano_module/program/computer_dos name = "DoS Traffic Generator" -/datum/nano_module/computer_dos/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) +/datum/nano_module/program/computer_dos/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) if(!ntnet_global) return var/datum/computer_file/program/ntnet_dos/PRG = program @@ -87,14 +87,14 @@ for(var/obj/machinery/ntnet_relay/R in ntnet_global.relays) if("[R.uid]" == href_list["PRG_target_relay"]) target = R - return + return 1 if(href_list["PRG_reset"]) if(target) target.dos_sources.Remove(src) target = null executed = 0 error = "" - return + return 1 if(href_list["PRG_execute"]) if(target) executed = 1 @@ -102,4 +102,4 @@ if(ntnet_global.intrusion_detection_enabled) ntnet_global.add_log("IDS WARNING - Excess traffic flood targeting relay [target.uid] detected from device: [computer.network_card.get_network_tag()]") ntnet_global.intrusion_detection_alarm = 1 - return \ No newline at end of file + return 1 diff --git a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm index baa7b5d291..96ca2cb75a 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm @@ -7,7 +7,7 @@ requires_ntnet = 0 available_on_ntnet = 0 available_on_syndinet = 1 - nanomodule_path = /datum/nano_module/revelation/ + nanomodule_path = /datum/nano_module/program/revelation/ var/armed = 0 /datum/computer_file/program/revelation/run_program(var/mob/living/user) @@ -49,16 +49,17 @@ if(!newname) return filedesc = newname + return 1 /datum/computer_file/program/revelation/clone() var/datum/computer_file/program/revelation/temp = ..() temp.armed = armed return temp -/datum/nano_module/revelation +/datum/nano_module/program/revelation name = "Revelation Virus" -/datum/nano_module/revelation/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) +/datum/nano_module/program/revelation/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) var/list/data = list() var/datum/computer_file/program/revelation/PRG = program if(!istype(PRG)) @@ -75,3 +76,4 @@ ui.set_initial_data(data) ui.open() ui.set_auto_update(1) + diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index 708e9dca5d..5e012dd902 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -1,23 +1,21 @@ /datum/computer_file/program/card_mod filename = "cardmod" filedesc = "ID card modification program" - nanomodule_path = /datum/nano_module/card_mod + nanomodule_path = /datum/nano_module/program/card_mod program_icon_state = "id" extended_desc = "Program for programming employee ID cards to access parts of the station." required_access = access_hop requires_ntnet = 0 size = 8 -/datum/nano_module/card_mod +/datum/nano_module/program/card_mod name = "ID card modification program" var/mod_mode = 1 var/is_centcom = 0 var/show_assignments = 0 -/datum/nano_module/card_mod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = list() - if(program) - data = program.get_header_data() +/datum/nano_module/program/card_mod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() data["src"] = "\ref[src]" data["station_name"] = station_name() @@ -84,13 +82,12 @@ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) - ui = new(user, src, ui_key, "identification_computer_lap.tmpl", name, 600, 700, state = state) + ui = new(user, src, ui_key, "mod_identification_computer.tmpl", name, 600, 700, state = state) ui.auto_update_layout = 1 ui.set_initial_data(data) ui.open() - ui.set_auto_update(0) -/datum/nano_module/card_mod/proc/format_jobs(list/jobs) +/datum/nano_module/program/card_mod/proc/format_jobs(list/jobs) var/obj/item/weapon/card/id/id_card = program.computer.card_slot.stored_card var/list/formatted = list() for(var/job in jobs) @@ -101,16 +98,18 @@ return formatted -/datum/nano_module/card_mod/proc/get_accesses(var/is_centcom = 0) - +/datum/nano_module/program/card_mod/proc/get_accesses(var/is_centcom = 0) return null /datum/computer_file/program/card_mod/Topic(href, href_list) - var/mob/living/user = usr + if(..()) + return 1 + + var/mob/user = usr var/obj/item/weapon/card/id/user_id_card = user.GetIdCard() var/obj/item/weapon/card/id/id_card = computer.card_slot.stored_card - var/datum/nano_module/card_mod/module = NM + var/datum/nano_module/program/card_mod/module = NM switch(href_list["action"]) if("switchm") if(href_list["target"] == "mod") @@ -135,14 +134,17 @@ Blood Type: [id_card.blood_type]

Access:
"} + + var/known_access_rights = get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM) for(var/A in id_card.access) - contents += " [get_access_desc(A)]" + if(A in known_access_rights) + contents += " [get_access_desc(A)]" if(!computer.nano_printer.print_text(contents,"access report")) usr << "Hardware error: Printer was unable to print the file. It may be out of paper." return else - computer.visible_message("[computer] prints out paper.") + computer.visible_message("\The [computer] prints out paper.") else var/contents = {"

Crew Manifest


@@ -152,14 +154,16 @@ usr << "Hardware error: Printer was unable to print the file. It may be out of paper." return else - computer.visible_message("[computer] prints out paper.") + computer.visible_message("\The [computer] prints out paper.") if("eject") if(computer && computer.card_slot) + if(id_card) + data_core.manifest_modify(id_card.registered_name, id_card.assignment) computer.proc_eject_id(user) if("terminate") if(computer && can_run(user, 1)) id_card.assignment = "Terminated" - id_card.access = list() + remove_nt_access(id_card) callHook("terminate_employee", list(id_card)) if("edit") if(computer && can_run(user, 1)) @@ -197,7 +201,8 @@ access = jobdatum.get_access() - id_card.access = access + remove_nt_access(id_card) + apply_access(id_card, access) id_card.assignment = t1 id_card.rank = t1 @@ -206,7 +211,7 @@ if(href_list["allowed"] && computer && can_run(user, 1)) var/access_type = text2num(href_list["access_target"]) var/access_allowed = text2num(href_list["allowed"]) - if(access_type in (get_all_centcom_access() + get_all_station_access())) + if(access_type in get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM)) id_card.access -= access_type if(!access_allowed) id_card.access += access_type @@ -214,5 +219,10 @@ id_card.name = text("[id_card.registered_name]'s ID Card ([id_card.assignment])") SSnanoui.update_uis(NM) - ..(href, href_list) - return 1 \ No newline at end of file + return 1 + +/datum/computer_file/program/card_mod/proc/remove_nt_access(var/obj/item/weapon/card/id/id_card) + id_card.access -= get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM) + +/datum/computer_file/program/card_mod/proc/apply_access(var/obj/item/weapon/card/id/id_card, var/list/accesses) + id_card.access |= accesses diff --git a/code/modules/modular_computers/file_system/programs/comm.dm b/code/modules/modular_computers/file_system/programs/comm.dm new file mode 100644 index 0000000000..2fd3639ecc --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/comm.dm @@ -0,0 +1,310 @@ +#define STATE_DEFAULT 1 +#define STATE_MESSAGELIST 2 +#define STATE_VIEWMESSAGE 3 +#define STATE_STATUSDISPLAY 4 +#define STATE_ALERT_LEVEL 5 +/datum/computer_file/program/comm + filename = "comm" + filedesc = "Command and communications program." + program_icon_state = "comm" + nanomodule_path = /datum/nano_module/program/comm + extended_desc = "Used to command and control the station. Can relay long-range communications." + required_access = access_heads + requires_ntnet = 1 + size = 12 + usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP + network_destination = "station long-range communication array" + var/datum/comm_message_listener/message_core = new + +/datum/computer_file/program/comm/clone() + var/datum/computer_file/program/comm/temp = ..() + temp.message_core.messages = null + temp.message_core.messages = message_core.messages.Copy() + return temp + +/datum/nano_module/program/comm + name = "Command and communications program" + var/current_status = STATE_DEFAULT + var/msg_line1 = "" + var/msg_line2 = "" + var/centcomm_message_cooldown = 0 + var/announcment_cooldown = 0 + var/datum/announcement/priority/crew_announcement = new + var/current_viewing_message_id = 0 + var/current_viewing_message = null + +/datum/nano_module/program/comm/New() + ..() + crew_announcement.newscast = 1 + +/datum/nano_module/program/comm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() + + if(program) + data["emagged"] = program.computer_emagged + data["net_comms"] = !!program.get_signal(NTNET_COMMUNICATION) //Double !! is needed to get 1 or 0 answer + data["net_syscont"] = !!program.get_signal(NTNET_SYSTEMCONTROL) + if(program.computer) + data["have_printer"] = !!program.computer.nano_printer + else + data["have_printer"] = 0 + else + data["emagged"] = 0 + data["net_comms"] = 1 + data["net_syscont"] = 1 + data["have_printer"] = 0 + + data["message_line1"] = msg_line1 + data["message_line2"] = msg_line2 + data["state"] = current_status + data["isAI"] = issilicon(usr) + data["authenticated"] = is_autenthicated(user) + data["current_security_level"] = security_level + data["current_security_level_title"] = num2seclevel(security_level) + + data["def_SEC_LEVEL_DELTA"] = SEC_LEVEL_DELTA + data["def_SEC_LEVEL_BLUE"] = SEC_LEVEL_BLUE + data["def_SEC_LEVEL_GREEN"] = SEC_LEVEL_GREEN + + var/datum/comm_message_listener/l = obtain_message_listener() + data["messages"] = l.messages + data["message_deletion_allowed"] = l != global_message_listener + data["message_current_id"] = current_viewing_message_id + if(current_viewing_message) + data["message_current"] = current_viewing_message + + if(emergency_shuttle.location()) + data["have_shuttle"] = 1 + if(emergency_shuttle.online()) + data["have_shuttle_called"] = 1 + else + data["have_shuttle_called"] = 0 + else + data["have_shuttle"] = 0 + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "mod_communication.tmpl", name, 550, 420, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + +/datum/nano_module/program/comm/proc/is_autenthicated(var/mob/user) + if(program) + return program.can_run(user) + return 1 + +/datum/nano_module/program/comm/proc/obtain_message_listener() + if(program) + var/datum/computer_file/program/comm/P = program + return P.message_core + return global_message_listener + +/datum/nano_module/program/comm/Topic(href, href_list) + if(..()) + return 1 + var/mob/user = usr + var/ntn_comm = !!program.get_signal(NTNET_COMMUNICATION) + var/ntn_cont = !!program.get_signal(NTNET_SYSTEMCONTROL) + var/datum/comm_message_listener/l = obtain_message_listener() + switch(href_list["action"]) + if("sw_menu") + current_status = text2num(href_list["target"]) + if("announce") + if(is_autenthicated(user) && !issilicon(usr) && ntn_comm) + if(user) + var/obj/item/weapon/card/id/id_card = user.GetIdCard() + crew_announcement.announcer = GetNameAndAssignmentFromId(id_card) + else + crew_announcement.announcer = "Unknown" + if(announcment_cooldown) + usr << "Please allow at least one minute to pass between announcements" + SSnanoui.update_uis(src) + return + var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") as null|text + if(!input || !can_still_topic()) + SSnanoui.update_uis(src) + return + crew_announcement.Announce(input) + announcment_cooldown = 1 + spawn(600)//One minute cooldown + announcment_cooldown = 0 + if("message") + if(href_list["target"] == "emagged") + if(program) + if(is_autenthicated(user) && program.computer_emagged && !issilicon(usr) && ntn_comm) + if(centcomm_message_cooldown) + usr << "Arrays recycling. Please stand by." + SSnanoui.update_uis(src) + return + var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") as null|text) + if(!input || !can_still_topic()) + SSnanoui.update_uis(src) + return + Syndicate_announce(input, usr) + usr << "Message transmitted." + log_say("[key_name(usr)] has made an illegal announcement: [input]") + centcomm_message_cooldown = 1 + spawn(300)//30 second cooldown + centcomm_message_cooldown = 0 + else if(href_list["target"] == "regular") + if(is_autenthicated(user) && !issilicon(usr) && ntn_comm) + if(centcomm_message_cooldown) + usr << "Arrays recycling. Please stand by." + SSnanoui.update_uis(src) + return + if(!is_relay_online())//Contact Centcom has a check, Syndie doesn't to allow for Traitor funs. + usr <<"No Emergency Bluespace Relay detected. Unable to transmit message." + SSnanoui.update_uis(src) + return + var/input = sanitize(input("Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") as null|text) + if(!input || !can_still_topic()) + SSnanoui.update_uis(src) + return + CentCom_announce(input, usr) + usr << "Message transmitted." + log_say("[key_name(usr)] has made an IA Centcomm announcement: [input]") + centcomm_message_cooldown = 1 + spawn(300) //30 second cooldown + centcomm_message_cooldown = 0 + if("shuttle") + if(is_autenthicated(user) && ntn_cont) + if(href_list["target"] == "call") + var/confirm = alert("Are you sure you want to call the shuttle?", name, "No", "Yes") + if(confirm == "Yes" && can_still_topic()) + call_shuttle_proc(usr) + if(href_list["target"] == "cancel" && !issilicon(usr)) + var/confirm = alert("Are you sure you want to cancel the shuttle?", name, "No", "Yes") + if(confirm == "Yes" && can_still_topic()) + cancel_call_proc(usr) + if("setstatus") + if(is_autenthicated(user) && ntn_cont) + switch(href_list["target"]) + if("line1") + var/linput = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", msg_line1) as text|null, 40), 40) + if(can_still_topic()) + msg_line1 = linput + if("line2") + var/linput = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", msg_line2) as text|null, 40), 40) + if(can_still_topic()) + msg_line2 = linput + if("message") + post_status("message", msg_line1, msg_line2) + if("alert") + post_status("alert", href_list["alert"]) + else + post_status(href_list["target"]) + + if("setalert") + if(is_autenthicated(user) && !issilicon(usr) && ntn_cont && ntn_comm) + var/current_level = text2num(href_list["target"]) + var/confirm = alert("Are you sure you want to change alert level to [num2seclevel(current_level)]?", name, "No", "Yes") + if(confirm == "Yes" && can_still_topic()) + var/old_level = security_level + if(!current_level) current_level = SEC_LEVEL_GREEN + if(current_level < SEC_LEVEL_GREEN) current_level = SEC_LEVEL_GREEN + if(current_level > SEC_LEVEL_BLUE) current_level = SEC_LEVEL_BLUE //Cannot engage delta with this + set_security_level(current_level) + if(security_level != old_level) + log_game("[key_name(usr)] has changed the security level to [get_security_level()].") + message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].") + switch(security_level) + if(SEC_LEVEL_GREEN) + feedback_inc("alert_comms_green",1) + if(SEC_LEVEL_BLUE) + feedback_inc("alert_comms_blue",1) + else + usr << "You press button, but red light flashes and nothing happens." //This should never happen + current_status = STATE_DEFAULT + if("viewmessage") + if(is_autenthicated(user) && ntn_comm) + current_viewing_message_id = text2num(href_list["target"]) + for(var/list/m in l.messages) + if(m["id"] == current_viewing_message_id) + current_viewing_message = m + current_status = STATE_VIEWMESSAGE + if("delmessage") + if(is_autenthicated(user) && ntn_comm && l != global_message_listener) + l.Remove(current_viewing_message) + current_status = STATE_MESSAGELIST + if("printmessage") + if(is_autenthicated(user) && ntn_comm) + if(program && program.computer && program.computer.nano_printer) + if(!program.computer.nano_printer.print_text(current_viewing_message["contents"],current_viewing_message["title"])) + usr << "Hardware error: Printer was unable to print the file. It may be out of paper." + else + program.computer.visible_message("\The [program.computer] prints out paper.") + + SSnanoui.update_uis(src) + +/datum/nano_module/program/comm/proc/post_status(var/command, var/data1, var/data2) + + var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + + if(!frequency) return + + + var/datum/signal/status_signal = new + status_signal.source = src + status_signal.transmission_method = 1 + status_signal.data["command"] = command + + switch(command) + if("message") + status_signal.data["msg1"] = data1 + status_signal.data["msg2"] = data2 + log_admin("STATUS: [key_name(usr)] set status screen message with [src]: [data1] [data2]") + if("alert") + status_signal.data["picture_state"] = data1 + + frequency.post_signal(src, status_signal) + +#undef STATE_DEFAULT +#undef STATE_MESSAGELIST +#undef STATE_VIEWMESSAGE +#undef STATE_STATUSDISPLAY +#undef STATE_ALERT_LEVEL + +/* +General message handling stuff +*/ +var/list/comm_message_listeners = list() //We first have to initialize list then we can use it. +var/datum/comm_message_listener/global_message_listener = new //May be used by admins +var/last_message_id = 0 + +proc/get_comm_message_id() + last_message_id = last_message_id + 1 + return last_message_id + +proc/post_comm_message(var/message_title, var/message_text) + var/list/message = list() + message["id"] = get_comm_message_id() + message["title"] = message_title + message["contents"] = message_text + + for (var/datum/comm_message_listener/l in comm_message_listeners) + l.Add(message) + + //Old console support + for (var/obj/machinery/computer/communications/comm in machines) + if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) + var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) + intercept.name = message_title + intercept.info = message_text + + comm.messagetitle.Add(message_title) + comm.messagetext.Add(message_text) + +/datum/comm_message_listener + var/list/messages + +/datum/comm_message_listener/New() + ..() + messages = list() + comm_message_listeners.Add(src) + +/datum/comm_message_listener/proc/Add(var/list/message) + messages[++messages.len] = message + +/datum/comm_message_listener/proc/Remove(var/list/message) + messages -= list(message) diff --git a/code/modules/modular_computers/file_system/programs/configurator.dm b/code/modules/modular_computers/file_system/programs/configurator.dm index b41223e3d5..5867efbdcb 100644 --- a/code/modules/modular_computers/file_system/programs/configurator.dm +++ b/code/modules/modular_computers/file_system/programs/configurator.dm @@ -12,16 +12,15 @@ size = 4 available_on_ntnet = 0 requires_ntnet = 0 - nanomodule_path = /datum/nano_module/computer_configurator/ + nanomodule_path = /datum/nano_module/program/computer_configurator/ -/datum/nano_module/computer_configurator +/datum/nano_module/program/computer_configurator name = "NTOS Computer Configuration Tool" var/obj/item/modular_computer/movable = null -/datum/nano_module/computer_configurator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) +/datum/nano_module/program/computer_configurator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) if(program) movable = program.computer - if(!istype(movable)) movable = null @@ -60,5 +59,4 @@ ui = new(user, src, ui_key, "laptop_configuration.tmpl", "NTOS Configuration Utility", 575, 700, state = state) ui.auto_update_layout = 1 ui.set_initial_data(data) - ui.open() - ui.set_auto_update(0) \ No newline at end of file + ui.open() \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm index 5f89081518..bdb14fb049 100644 --- a/code/modules/modular_computers/file_system/programs/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/file_browser.dm @@ -7,71 +7,82 @@ requires_ntnet = 0 available_on_ntnet = 0 undeletable = 1 - nanomodule_path = /datum/nano_module/computer_filemanager/ + nanomodule_path = /datum/nano_module/program/computer_filemanager/ var/open_file var/error /datum/computer_file/program/filemanager/Topic(href, href_list) + if(..()) + return 1 + if(href_list["PRG_openfile"]) + . = 1 open_file = href_list["PRG_openfile"] if(href_list["PRG_newtextfile"]) + . = 1 var/newname = sanitize(input(usr, "Enter file name or leave blank to cancel:", "File rename")) if(!newname) - return + return 1 var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive if(!HDD) - return + return 1 var/datum/computer_file/data/F = new/datum/computer_file/data() F.filename = newname F.filetype = "TXT" HDD.store_file(F) if(href_list["PRG_deletefile"]) + . = 1 var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive if(!HDD) - return + return 1 var/datum/computer_file/file = HDD.find_file_by_name(href_list["PRG_deletefile"]) if(!file || file.undeletable) - return + return 1 HDD.remove_file(file) if(href_list["PRG_usbdeletefile"]) + . = 1 var/obj/item/weapon/computer_hardware/hard_drive/RHDD = computer.portable_drive if(!RHDD) - return + return 1 var/datum/computer_file/file = RHDD.find_file_by_name(href_list["PRG_usbdeletefile"]) if(!file || file.undeletable) - return + return 1 RHDD.remove_file(file) if(href_list["PRG_closefile"]) + . = 1 open_file = null error = null if(href_list["PRG_clone"]) + . = 1 var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive if(!HDD) - return + return 1 var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_clone"]) if(!F || !istype(F)) - return + return 1 var/datum/computer_file/C = F.clone(1) HDD.store_file(C) if(href_list["PRG_rename"]) + . = 1 var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive if(!HDD) - return + return 1 var/datum/computer_file/file = HDD.find_file_by_name(href_list["PRG_rename"]) if(!file || !istype(file)) - return + return 1 var/newname = sanitize(input(usr, "Enter new file name:", "File rename", file.filename)) if(file && newname) file.filename = newname if(href_list["PRG_edit"]) + . = 1 if(!open_file) - return + return 1 var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive if(!HDD) - return + return 1 var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) if(!F || !istype(F)) - return + return 1 // 16384 is the limit for file length in characters. Currently, papers have value of 2048 so this is 8 times as long, since we can't edit parts of the file independently. var/newtext = sanitize(html_decode(input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", F.stored_data) as message), 16384) if(F) @@ -86,41 +97,45 @@ error = "I/O error: Unable to overwrite file. Hard drive is probably full. You may want to backup your changes before closing this window:

[F.stored_data]

" HDD.store_file(backup) if(href_list["PRG_printfile"]) + . = 1 if(!open_file) - return + return 1 var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive if(!HDD) - return + return 1 var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) if(!F || !istype(F)) - return + return 1 if(!computer.nano_printer) error = "Missing Hardware: Your computer does not have required hardware to complete this operation." - return + return 1 if(!computer.nano_printer.print_text(parse_tags(F.stored_data))) error = "Hardware error: Printer was unable to print the file. It may be out of paper." - return + return 1 if(href_list["PRG_copytousb"]) + . = 1 var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive if(!HDD || !RHDD) - return + return 1 var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_copytousb"]) if(!F || !istype(F)) - return + return 1 var/datum/computer_file/C = F.clone(0) RHDD.store_file(C) if(href_list["PRG_copyfromusb"]) + . = 1 var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive if(!HDD || !RHDD) - return + return 1 var/datum/computer_file/F = RHDD.find_file_by_name(href_list["PRG_copyfromusb"]) if(!F || !istype(F)) - return + return 1 var/datum/computer_file/C = F.clone(0) HDD.store_file(C) - ..(href, href_list) + if(.) + SSnanoui.update_uis(NM) /datum/computer_file/program/filemanager/proc/parse_tags(var/t) t = replacetext(t, "\[center\]", "
") @@ -160,18 +175,13 @@ return t -/datum/nano_module/computer_filemanager +/datum/nano_module/program/computer_filemanager name = "NTOS File Manager" -/datum/nano_module/computer_filemanager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - +/datum/nano_module/program/computer_filemanager/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + var/list/data = host.initial_data() var/datum/computer_file/program/filemanager/PRG - var/list/data = list() - if(program) - data = program.get_header_data() - PRG = program - else - return + PRG = program var/obj/item/weapon/computer_hardware/hard_drive/HDD var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD @@ -223,5 +233,5 @@ ui.auto_update_layout = 1 ui.set_initial_data(data) ui.open() - ui.set_auto_update(0) + diff --git a/code/modules/modular_computers/file_system/programs/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/ntdownloader.dm index c9c601a66d..b0bb56928e 100644 --- a/code/modules/modular_computers/file_system/programs/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/ntdownloader.dm @@ -9,7 +9,7 @@ requires_ntnet = 1 requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD available_on_ntnet = 0 - nanomodule_path = /datum/nano_module/computer_ntnetdownload/ + nanomodule_path = /datum/nano_module/program/computer_ntnetdownload/ ui_header = "downloader_finished.gif" var/datum/computer_file/program/downloaded_file = null var/hacked_download = 0 @@ -89,22 +89,21 @@ if(href_list["PRG_downloadfile"]) if(!downloaded_file) begin_file_download(href_list["PRG_downloadfile"]) - return + return 1 if(href_list["PRG_reseterror"]) if(downloaderror) download_completion = 0 download_netspeed = 0 downloaded_file = null downloaderror = "" - return + return 1 return 0 - -/datum/nano_module/computer_ntnetdownload +/datum/nano_module/program/computer_ntnetdownload name = "Network Downloader" var/obj/item/modular_computer/my_computer = null -/datum/nano_module/computer_ntnetdownload/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) +/datum/nano_module/program/computer_ntnetdownload/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) if(program) my_computer = program.computer @@ -162,4 +161,4 @@ ui.auto_update_layout = 1 ui.set_initial_data(data) ui.open() - ui.set_auto_update(1) \ No newline at end of file + ui.set_auto_update(1) diff --git a/code/modules/modular_computers/file_system/programs/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/ntmonitor.dm index bd7fe683a8..9400ad538e 100644 --- a/code/modules/modular_computers/file_system/programs/ntmonitor.dm +++ b/code/modules/modular_computers/file_system/programs/ntmonitor.dm @@ -15,11 +15,7 @@ /datum/nano_module/computer_ntnetmonitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) if(!ntnet_global) return - - var/list/data = list() - if(program) - data = program.get_header_data() - + var/list/data = host.initial_data() data["ntnetstatus"] = ntnet_global.check_function() data["ntnetrelays"] = ntnet_global.relays.len @@ -38,7 +34,8 @@ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "ntnet_monitor.tmpl", "NTNet Diagnostics and Monitoring Tool", 575, 700, state = state) - ui.auto_update_layout = 1 + if(host.update_layout()) + ui.auto_update_layout = 1 ui.set_initial_data(data) ui.open() ui.set_auto_update(1) @@ -47,14 +44,17 @@ if(..()) return 1 if(href_list["resetIDS"]) + . = 1 if(ntnet_global) ntnet_global.resetIDS() return 1 if(href_list["toggleIDS"]) + . = 1 if(ntnet_global) ntnet_global.toggleIDS() return 1 if(href_list["toggleWireless"]) + . = 1 if(!ntnet_global) return 1 @@ -66,20 +66,23 @@ // NTNet is enabled and user is about to shut it down. Let's ask them if they really want to do it, as wirelessly connected computers won't connect without NTNet being enabled (which may prevent people from turning it back on) var/mob/user = usr if(!user) - return + return 1 var/response = alert(user, "Really disable NTNet wireless? If your computer is connected wirelessly you won't be able to turn it back on! This will affect all connected wireless devices.", "NTNet shutdown", "Yes", "No") if(response == "Yes") ntnet_global.setting_disabled = 1 return 1 if(href_list["purgelogs"]) + . = 1 if(ntnet_global) ntnet_global.purge_logs() if(href_list["updatemaxlogs"]) + . = 1 var/mob/user = usr var/logcount = text2num(input(user,"Enter amount of logs to keep in memory ([MIN_NTNET_LOGS]-[MAX_NTNET_LOGS]):")) if(ntnet_global) ntnet_global.update_max_log_count(logcount) if(href_list["toggle_function"]) + . = 1 if(!ntnet_global) - return - ntnet_global.toggle_function(href_list["toggle_function"]) \ No newline at end of file + return 1 + ntnet_global.toggle_function(href_list["toggle_function"]) diff --git a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm index 42dab1bd74..c16baf2895 100644 --- a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm @@ -9,7 +9,7 @@ network_destination = "NTNRC server" ui_header = "ntnrc_idle.gif" available_on_ntnet = 1 - nanomodule_path = /datum/nano_module/computer_chatclient/ + nanomodule_path = /datum/nano_module/program/computer_chatclient/ var/last_message = null // Used to generate the toolbar icon var/username var/datum/ntnet_conversation/channel = null @@ -20,9 +20,13 @@ username = "DefaultUser[rand(100, 999)]" /datum/computer_file/program/chatclient/Topic(href, href_list) + if(..()) + return 1 + if(href_list["PRG_speak"]) + . = 1 if(!channel) - return + return 1 var/mob/living/user = usr var/message = sanitize(input(user, "Enter message or leave blank to cancel: ")) if(!message || !channel) @@ -30,6 +34,7 @@ channel.add_message(message, username) if(href_list["PRG_joinchannel"]) + . = 1 var/datum/ntnet_conversation/C for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels) if(chan.id == text2num(href_list["PRG_joinchannel"])) @@ -37,11 +42,11 @@ break if(!C) - return + return 1 if(netadmin_mode) channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others. - return + return 1 if(C.password) var/mob/living/user = usr @@ -49,14 +54,16 @@ if(C && (password == C.password)) C.add_client(src) channel = C - return + return 1 C.add_client(src) channel = C if(href_list["PRG_leavechannel"]) + . = 1 if(channel) channel.remove_client(src) channel = null if(href_list["PRG_newchannel"]) + . = 1 var/mob/living/user = usr var/channel_title = sanitize(input(user,"Enter channel name or leave blank to cancel:")) if(!channel_title) @@ -67,12 +74,13 @@ channel = C C.title = channel_title if(href_list["PRG_toggleadmin"]) + . = 1 if(netadmin_mode) netadmin_mode = 0 if(channel) channel.remove_client(src) // We shouldn't be in channel's user list, but just in case... channel = null - return + return 1 var/mob/living/user = usr if(can_run(usr, 1, access_network)) if(channel) @@ -85,21 +93,23 @@ return netadmin_mode = 1 if(href_list["PRG_changename"]) + . = 1 var/mob/living/user = usr var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:")) if(!newname) - return + return 1 if(channel) channel.add_status_message("[username] is now known as [newname].") username = newname if(href_list["PRG_savelog"]) + . = 1 if(!channel) return var/mob/living/user = usr var/logname = input(user,"Enter desired logfile name (.log) or leave blank to cancel:") if(!logname || !channel) - return + return 1 var/datum/computer_file/data/logfile = new/datum/computer_file/data/logfile() // Now we will generate HTML-compliant file that can actually be viewed/printed. logfile.filename = logname @@ -112,14 +122,15 @@ if(!computer) // This program shouldn't even be runnable without computer. CRASH("Var computer is null!") - return + return 1 if(!computer.hard_drive) computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.") else // In 99.9% cases this will mean our HDD is full computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.") if(href_list["PRG_renamechannel"]) + . = 1 if(!operator_mode || !channel) - return + return 1 var/mob/living/user = usr var/newname = sanitize(input(user, "Enter new channel name or leave blank to cancel:")) if(!newname || !channel) @@ -127,24 +138,25 @@ channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.") channel.title = newname if(href_list["PRG_deletechannel"]) + . = 1 if(channel && ((channel.operator == src) || netadmin_mode)) - del(channel) + qdel(channel) + channel = null if(href_list["PRG_setpassword"]) + . = 1 if(!channel || ((channel.operator != src) && !netadmin_mode)) - return + return 1 var/mob/living/user = usr var/newpassword = sanitize(input(user, "Enter new password for this channel. Leave blank to cancel, enter 'nopassword' to remove password completely:")) if(!channel || !newpassword || ((channel.operator != src) && !netadmin_mode)) - return + return 1 if(newpassword == "nopassword") channel.password = "" else channel.password = newpassword - ..(href, href_list) - /datum/computer_file/program/chatclient/process_tick() ..() if(program_state != PROGRAM_STATE_KILLED) @@ -166,10 +178,10 @@ channel = null ..(forced) -/datum/nano_module/computer_chatclient +/datum/nano_module/program/computer_chatclient name = "NTNet Relay Chat Client" -/datum/nano_module/computer_chatclient/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) +/datum/nano_module/program/computer_chatclient/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) if(!ntnet_global || !ntnet_global.chat_channels) return @@ -215,4 +227,4 @@ ui.auto_update_layout = 1 ui.set_initial_data(data) ui.open() - ui.set_auto_update(1) \ No newline at end of file + ui.set_auto_update(1) diff --git a/code/modules/modular_computers/file_system/programs/nttransfer.dm b/code/modules/modular_computers/file_system/programs/nttransfer.dm index de2dd65aa1..404238d326 100644 --- a/code/modules/modular_computers/file_system/programs/nttransfer.dm +++ b/code/modules/modular_computers/file_system/programs/nttransfer.dm @@ -10,7 +10,7 @@ var/global/nttransfer_uid = 0 requires_ntnet_feature = NTNET_PEERTOPEER network_destination = "other device via P2P tunnel" available_on_ntnet = 1 - nanomodule_path = /datum/nano_module/computer_nttransfer/ + nanomodule_path = /datum/nano_module/program/computer_nttransfer/ var/error = "" // Error screen var/server_password = "" // Optional password to download the file. @@ -87,13 +87,10 @@ var/global/nttransfer_uid = 0 download_completion = 0 - - - -/datum/nano_module/computer_nttransfer +/datum/nano_module/program/computer_nttransfer name = "NTNet P2P Transfer Client" -/datum/nano_module/computer_nttransfer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) +/datum/nano_module/program/computer_nttransfer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) if(!program) return var/datum/computer_file/program/nttransfer/PRG = program @@ -161,7 +158,7 @@ var/global/nttransfer_uid = 0 return downloaded_file = remote.provided_file.clone() remote.connected_clients.Add(src) - return + return 1 if(href_list["PRG_reset"]) error = "" upload_menu = 0 @@ -171,7 +168,7 @@ var/global/nttransfer_uid = 0 for(var/datum/computer_file/program/nttransfer/T in connected_clients) T.crash_download("Remote server has forcibly closed the connection") provided_file = null - return + return 1 if(href_list["PRG_setpassword"]) var/pass = sanitize(input(usr, "Enter new server password. Leave blank to cancel, input 'none' to disable password.", "Server security", "none")) if(!pass) @@ -180,7 +177,7 @@ var/global/nttransfer_uid = 0 server_password = "" return server_password = pass - return + return 1 if(href_list["PRG_uploadfile"]) for(var/datum/computer_file/F in computer.hard_drive.stored_files) if("[F.uid]" == href_list["PRG_uploadfile"]) @@ -191,7 +188,7 @@ var/global/nttransfer_uid = 0 ntnet_global.fileservers.Add(src) return error = "I/O Error: Unable to locate file on hard drive." - return + return 1 if(href_list["PRG_uploadmenu"]) upload_menu = 1 - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/nano/modules/alarm_monitor.dm b/code/modules/nano/modules/alarm_monitor.dm index 7ca7a3a26b..f42c326678 100644 --- a/code/modules/nano/modules/alarm_monitor.dm +++ b/code/modules/nano/modules/alarm_monitor.dm @@ -64,10 +64,7 @@ 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 = default_state) - var/data[0] - - if(program) - data = program.get_header_data() + var/list/data = host.initial_data() var/categories[0] for(var/datum/alarm_handler/AH in alarm_handlers) @@ -94,7 +91,7 @@ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state) - if(program) // This is necessary to ensure the status bar remains updated along with rest of the UI. + if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. ui.auto_update_layout = 1 ui.set_initial_data(data) ui.open() diff --git a/code/modules/nano/modules/atmos_control.dm b/code/modules/nano/modules/atmos_control.dm index 154ac0d99d..c077dc1283 100644 --- a/code/modules/nano/modules/atmos_control.dm +++ b/code/modules/nano/modules/atmos_control.dm @@ -30,13 +30,10 @@ return 1 /datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) - var/data[0] + var/list/data = host.initial_data() var/alarms[0] var/turf/T = get_turf(nano_host()) - if(program) - data = program.get_header_data() - // TODO: Move these to a cache, similar to cameras for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines)) if(!monitored_alarms.len && alarm.alarms_hidden) @@ -54,7 +51,7 @@ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 625, 625, state = state) - if(program) // This is necessary to ensure the status bar remains updated along with rest of the UI. + if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. ui.auto_update_layout = 1 // adding a template with the key "mapContent" enables the map ui functionality ui.add_template("mapContent", "atmos_control_map_content.tmpl") diff --git a/code/modules/nano/modules/crew_monitor.dm b/code/modules/nano/modules/crew_monitor.dm index a593368aee..7ea34f8a12 100644 --- a/code/modules/nano/modules/crew_monitor.dm +++ b/code/modules/nano/modules/crew_monitor.dm @@ -16,9 +16,7 @@ return 1 /datum/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/data[0] - if(program) - data = program.get_header_data() + var/list/data = host.initial_data() var/turf/T = get_turf(nano_host()) data["isAI"] = isAI(user) diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 3d790b1194..fd2ed900f2 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -100,7 +100,7 @@ return generate_data(check_whitelist, whitelist, blacklist) - var/data[0] + var/list/data = host.initial_data() data["specimen"] = owner.species.name data["gender"] = owner.gender diff --git a/code/modules/nano/modules/nano_module.dm b/code/modules/nano/modules/nano_module.dm index 0b79001192..f8001682ec 100644 --- a/code/modules/nano/modules/nano_module.dm +++ b/code/modules/nano/modules/nano_module.dm @@ -1,10 +1,10 @@ /datum/nano_module var/name - var/host + var/datum/host var/datum/computer_file/program/program = null // Program-Based computer program that runs this nano module. Defaults to null. -/datum/nano_module/New(var/host) - src.host = host +/datum/nano_module/New(var/host, var/program) + src.program = program // Machinery-based computers wouldn't work w/o this as nano will assume they're items inside containers. if(istype(host, /obj/item/modular_computer/processor)) var/obj/item/modular_computer/processor/H = host @@ -12,8 +12,11 @@ else src.host = host -/datum/nano_module/Destroy() - host = null +/datum/nano_module/Topic(href, href_list) + // Calls forwarded to PROGRAM itself should begin with "PRG_" + // Calls forwarded to COMPUTER running the program should begin with "PC_" + if(program && program.Topic(href, href_list)) + return TRUE return ..() /datum/nano_module/nano_host() @@ -22,9 +25,8 @@ /datum/nano_module/proc/can_still_topic(var/datum/topic_state/state = default_state) return CanUseTopic(usr, state) == STATUS_INTERACTIVE -/datum/nano_module/Topic(href, href_list) - // Calls forwarded to PROGRAM itself should begin with "PRG_" - // Calls forwarded to COMPUTER running the program should begin with "PC_" - if(program) - program.Topic(href, href_list) - return ..() \ No newline at end of file +/datum/proc/initial_data() + return list() + +/datum/proc/update_layout() + return FALSE diff --git a/code/modules/nano/modules/power_monitor.dm b/code/modules/nano/modules/power_monitor.dm index db63ebdf94..3bd87cc5bc 100644 --- a/code/modules/nano/modules/power_monitor.dm +++ b/code/modules/nano/modules/power_monitor.dm @@ -17,9 +17,7 @@ // If PC is not null header template is loaded. Use PC.get_header_data() to get relevant nanoui data from it. All data entries begin with "PC_...." // In future it may be expanded to other modular computer devices. /datum/nano_module/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = list() - if(program) - data = program.get_header_data() + var/list/data = host.initial_data() var/list/sensors = list() // Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading. @@ -43,7 +41,7 @@ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "power_monitor.tmpl", "Power Monitoring Console", 800, 500, state = state) - if(program) // This is necessary to ensure the status bar remains updated along with rest of the UI. + if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. ui.auto_update_layout = 1 // adding a template with the key "mapContent" enables the map ui functionality ui.add_template("mapContent", "power_monitor_map_content.tmpl") diff --git a/code/modules/nano/modules/rcon.dm b/code/modules/nano/modules/rcon.dm index 0153b2ad9f..67a949a828 100644 --- a/code/modules/nano/modules/rcon.dm +++ b/code/modules/nano/modules/rcon.dm @@ -9,9 +9,7 @@ /datum/nano_module/rcon/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1, var/datum/topic_state/state = default_state) FindDevices() // Update our devices list - var/data[0] - if(program) - data = program.get_header_data() + var/list/data = host.initial_data() // SMES DATA (simplified view) var/list/smeslist[0] @@ -43,7 +41,7 @@ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "rcon.tmpl", "RCON Console", 600, 400, state = state) - if(program) // This is necessary to ensure the status bar remains updated along with rest of the UI. + if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. ui.auto_update_layout = 1 ui.set_initial_data(data) ui.open() diff --git a/nano/templates/mod_communication.tmpl b/nano/templates/mod_communication.tmpl new file mode 100644 index 0000000000..cd943d2122 --- /dev/null +++ b/nano/templates/mod_communication.tmpl @@ -0,0 +1,66 @@ +{{if data.authenticated}} + {{if data.state === 1}} +
{{:helper.link('Make An Announcement', null, {'action' : 'announce'}, data.isAI || !data.net_comms ? 'disabled' : null)}}
+
{{if data.emagged}} + {{:helper.link('Send an emergency message to [UNKNOWN]', null, {'action' : 'message', 'target' : 'emagged'}, data.isAI || !data.net_comms ? 'disabled' : null)}} + {{else}} + {{:helper.link('Send an emergency message to ' + data.boss_short, null, {'action' : 'message', 'target' : 'regular'}, data.isAI || !data.net_comms ? 'disabled' : null)}} + {{/if}}
+
{{:helper.link('Change alert level', null, {'action' : 'sw_menu', 'target' : 5}, data.isAI || !data.net_syscont || !data.net_comms ? 'disabled' : null)}}
+
{{if data.have_shuttle && data.have_shuttle_called}} + {{:helper.link('Cancel Shuttle Call', null, {'action' : 'shuttle', 'target' : 'cancel'}, data.isAI || !data.net_syscont ? 'disabled' : null)}} + {{else data.have_shuttle && !data.have_shuttle_called}} + {{:helper.link('Call Emergency Shuttle', null, {'action' : 'shuttle', 'target' : 'call'}, !data.net_syscont ? 'disabled' : null)}} + {{/if}}
+
{{:helper.link('Set Status Display', null, {'action' : 'sw_menu', 'target' : 4}, !data.net_syscont ? 'disabled' : null)}}
+
{{:helper.link('Message List', null, {'action' : 'sw_menu', 'target' : 2}, !data.net_comms ? 'disabled' : null)}}
+ {{else data.state === 2}} + Messages: + {{for data.messages}} +
{{:helper.link(value.title, null, {'action' : 'viewmessage', 'target' : value.id})}}
+ {{empty}} +
There are no messages.
+ {{/for}} +
{{:helper.link('Back', null, {'action' : 'sw_menu', 'target' : 1})}}
+ {{else data.state === 3}} +
Title: {{:data.message_current.title}}
+
Contents:
{{:data.message_current.contents}}
+
+ {{:helper.link('Delete', null, {'action' : 'delmessage'})}} + {{if data.have_printer}} + {{:helper.link('Print', null, {'action' : 'printmessage'})}} + {{/if}} + {{:helper.link('Back', null, {'action' : 'sw_menu', 'target' : 2})}} +
+ {{else data.state === 4}} + Set status displays: +
{{:helper.link('Clear', null, {'action' : 'setstatus', 'target' : 'blank'})}}
+
{{:helper.link('Station Time', null, {'action' : 'setstatus', 'target' : 'time'})}}
+
{{:helper.link('Shuttle ETA', null, {'action' : 'setstatus', 'target' : 'shuttle'})}}
+
{{:helper.link('Message', null, {'action' : 'setstatus', 'target' : 'message'})}} +
    +
  • Line 1: {{:helper.link(data.message_line1 ? data.message_line1 : '(none)', null, {'action' : 'setstatus', 'target' : 'line1'})}}
  • +
  • Line 2: {{:helper.link(data.message_line2 ? data.message_line2 : '(none)', null, {'action' : 'setstatus', 'target' : 'line2'})}}
  • +
+
Alert: {{:helper.link('Red Alert', null, {'action' : 'setstatus', 'target' : 'alert', 'alert' : 'redalert'})}} + {{:helper.link('Lockdown', null, {'action' : 'setstatus', 'target' : 'alert', 'alert' : 'lockdown'})}} + {{:helper.link('Biohazard', null, {'action' : 'setstatus', 'target' : 'alert', 'alert' : 'biohazard'})}}
+ {{:helper.link('Back', null, {'action' : 'sw_menu', 'target' : 1})}} + {{else data.state === 5}} + Current Alert level is {{:data.current_security_level_title}} + {{if data.current_security_level === data.def_SEC_LEVEL_DELTA}} +
The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate.
+ {{else}} +
Set status:
+
{{:helper.link('Blue', null, {'action' : 'setalert', 'target' : data.def_SEC_LEVEL_BLUE}, data.current_security_level === data.def_SEC_LEVEL_BLUE || data.isAI ? 'disabled' : null)}}
+
{{:helper.link('Green', null, {'action' : 'setalert', 'target' : data.def_SEC_LEVEL_GREEN}, data.current_security_level === data.def_SEC_LEVEL_GREEN || data.isAI ? 'disabled' : null)}}
+ {{/if}} +
+
{{:helper.link('Back', null, {'action' : 'sw_menu', 'target' : 1})}}
+ {{else}} + Something went wrong. Please reset your console. +
{{:helper.link('Back', null, {'action' : 'sw_menu', 'target' : 1})}}
+ {{/if}} +{{else}} + You are unauthorised. +{{/if}} diff --git a/nano/templates/identification_computer_lap.tmpl b/nano/templates/mod_identification_computer.tmpl similarity index 100% rename from nano/templates/identification_computer_lap.tmpl rename to nano/templates/mod_identification_computer.tmpl diff --git a/polaris.dme b/polaris.dme index bae26201a9..ccd27f2f85 100644 --- a/polaris.dme +++ b/polaris.dme @@ -2111,7 +2111,9 @@ #include "code\modules\modular_computers\file_system\program_events.dm" #include "code\modules\modular_computers\file_system\programs\_engineering.dm" #include "code\modules\modular_computers\file_system\programs\_medical.dm" +#include "code\modules\modular_computers\file_system\programs\_program.dm" #include "code\modules\modular_computers\file_system\programs\card.dm" +#include "code\modules\modular_computers\file_system\programs\comm.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"