diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index a48202a4e30..0c554b3139e 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -84,6 +84,12 @@ #define PROGRAM_STATE_KILLED 0 #define PROGRAM_STATE_BACKGROUND 1 #define PROGRAM_STATE_ACTIVE 2 +//Program categories +#define PROGRAM_CATEGORY_CREW "Crew" +#define PROGRAM_CATEGORY_ENGI "Engineering" +#define PROGRAM_CATEGORY_ROBO "Robotics" +#define PROGRAM_CATEGORY_SUPL "Supply" +#define PROGRAM_CATEGORY_MISC "Other" #define FIREDOOR_OPEN 1 #define FIREDOOR_CLOSED 2 diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 699ccb0947b..751332c8623 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -15,6 +15,8 @@ var/filedesc = "Unknown Program" /// Short description of this program's function. var/extended_desc = "N/A" + /// Category in the NTDownloader. + var/category = PROGRAM_CATEGORY_MISC /// Program-specific screen icon state var/program_icon_state = null /// Set to 1 for program to require nonstop NTNet connection to run. If NTNet connection is lost program crashes. diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm index 8e3bbb20f56..eafbcb6126d 100644 --- a/code/modules/modular_computers/file_system/programs/airestorer.dm +++ b/code/modules/modular_computers/file_system/programs/airestorer.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/aidiag filename = "aidiag" filedesc = "NT FRK" + category = PROGRAM_CATEGORY_ROBO program_icon_state = "generic" extended_desc = "Firmware Restoration Kit, capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot." size = 12 diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm index 646d9892ba4..8ef71a93067 100644 --- a/code/modules/modular_computers/file_system/programs/alarm.dm +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/alarm_monitor filename = "alarmmonitor" filedesc = "Canary" + category = PROGRAM_CATEGORY_ENGI ui_header = "alarm_green.gif" program_icon_state = "alert-green" extended_desc = "This program provides visual interface for a station's alarm system." diff --git a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm index 8709526de68..5d2090f2bde 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/contract_uplink filename = "contractor uplink" filedesc = "Syndicate Contractor Uplink" + category = PROGRAM_CATEGORY_MISC program_icon_state = "assign" extended_desc = "A standard, Syndicate issued system for handling important contracts while on the field." size = 10 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 6bab999facd..c76f85143e3 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/ntnet_dos filename = "ntn_dos" filedesc = "DoS Traffic Generator" + category = PROGRAM_CATEGORY_MISC program_icon_state = "hostile" extended_desc = "This advanced script can perform denial of service attacks against NTNet quantum relays. The system administrator will probably notice this. Multiple devices can run this program together against same relay for increased effect" size = 20 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 ba24a5ab3e0..829f9ccef8c 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/revelation filename = "revelation" filedesc = "Revelation" + category = PROGRAM_CATEGORY_MISC program_icon_state = "hostile" extended_desc = "This virus can destroy hard drive of system it is executed on. It may be obfuscated to look like another non-malicious program. Once armed, it will destroy the system upon next execution." size = 13 diff --git a/code/modules/modular_computers/file_system/programs/atmosscan.dm b/code/modules/modular_computers/file_system/programs/atmosscan.dm index f718977d5b2..b6c040741e0 100644 --- a/code/modules/modular_computers/file_system/programs/atmosscan.dm +++ b/code/modules/modular_computers/file_system/programs/atmosscan.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/atmosscan filename = "atmosscan" filedesc = "AtmoZphere" + category = PROGRAM_CATEGORY_ENGI program_icon_state = "air" extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device." size = 4 diff --git a/code/modules/modular_computers/file_system/programs/borg_monitor.dm b/code/modules/modular_computers/file_system/programs/borg_monitor.dm index 6fa36fed96a..4b350051030 100644 --- a/code/modules/modular_computers/file_system/programs/borg_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/borg_monitor.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/borg_monitor filename = "siliconnect" filedesc = "SiliConnect" + category = PROGRAM_CATEGORY_ROBO ui_header = "borg_mon.gif" program_icon_state = "generic" extended_desc = "This program allows for remote monitoring of station cyborgs." @@ -97,6 +98,7 @@ /datum/computer_file/program/borg_monitor/syndicate filename = "roboverlord" filedesc = "Roboverlord" + category = PROGRAM_CATEGORY_ROBO ui_header = "borg_mon.gif" program_icon_state = "generic" extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs." diff --git a/code/modules/modular_computers/file_system/programs/bounty_board.dm b/code/modules/modular_computers/file_system/programs/bounty_board.dm index 9c42a28a9bc..d008d5e72be 100644 --- a/code/modules/modular_computers/file_system/programs/bounty_board.dm +++ b/code/modules/modular_computers/file_system/programs/bounty_board.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/bounty_board filename = "bountyboard" filedesc = "Bounty Board Request Network" + category = PROGRAM_CATEGORY_SUPL program_icon_state = "bountyboard" extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible.." requires_ntnet = TRUE diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index b42c6812938..307483c209b 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -1,8 +1,9 @@ /datum/computer_file/program/budgetorders filename = "orderapp" - filedesc = "Nanotrasen Internal Requisition Network (NIRN)" + filedesc = "NT IRN" + category = PROGRAM_CATEGORY_SUPL program_icon_state = "request" - extended_desc = "A request network that utilizes the Nanotrasen Ordering network to purchase supplies using a department budget account." + extended_desc = "Nanotrasen Internal Requisition Network interface for supply purchasing using a department budget account." requires_ntnet = TRUE transfer_access = ACCESS_HEADS usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index e9c8fd9110d..37629269292 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -9,6 +9,7 @@ /datum/computer_file/program/card_mod filename = "plexagonidwriter" filedesc = "Plexagon Access Management" + category = PROGRAM_CATEGORY_CREW program_icon_state = "id" extended_desc = "Program for programming employee ID cards to access parts of the station." transfer_access = ACCESS_HEADS diff --git a/code/modules/modular_computers/file_system/programs/cargoship.dm b/code/modules/modular_computers/file_system/programs/cargoship.dm index 89a3b3247db..6393a5c3b1c 100644 --- a/code/modules/modular_computers/file_system/programs/cargoship.dm +++ b/code/modules/modular_computers/file_system/programs/cargoship.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/shipping filename = "shipping" filedesc = "GrandArk Exporter" + category = PROGRAM_CATEGORY_SUPL program_icon_state = "shipping" extended_desc = "A combination printer/scanner app that enables modular computers to print barcodes for easy scanning and shipping." size = 6 diff --git a/code/modules/modular_computers/file_system/programs/crewmanifest.dm b/code/modules/modular_computers/file_system/programs/crewmanifest.dm index 08e5df04bc6..99483d4e789 100644 --- a/code/modules/modular_computers/file_system/programs/crewmanifest.dm +++ b/code/modules/modular_computers/file_system/programs/crewmanifest.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/crew_manifest filename = "plexagoncrew" filedesc = "Plexagon Crew List" + category = PROGRAM_CATEGORY_CREW program_icon_state = "id" extended_desc = "Program for viewing and printing the current crew manifest" transfer_access = ACCESS_HEADS diff --git a/code/modules/modular_computers/file_system/programs/jobmanagement.dm b/code/modules/modular_computers/file_system/programs/jobmanagement.dm index 3f21d2cf2c2..4df92541b35 100644 --- a/code/modules/modular_computers/file_system/programs/jobmanagement.dm +++ b/code/modules/modular_computers/file_system/programs/jobmanagement.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/job_management filename = "plexagoncore" filedesc = "Plexagon HR Core" + category = PROGRAM_CATEGORY_CREW program_icon_state = "id" extended_desc = "Program for viewing and changing job slot avalibility." transfer_access = ACCESS_HEADS diff --git a/code/modules/modular_computers/file_system/programs/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/ntdownloader.dm index f3fa6df2b3a..56283e3c8be 100644 --- a/code/modules/modular_computers/file_system/programs/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/ntdownloader.dm @@ -22,6 +22,13 @@ var/emagged = FALSE var/list/main_repo var/list/antag_repo + var/list/show_categories = list( + PROGRAM_CATEGORY_CREW, + PROGRAM_CATEGORY_ENGI, + PROGRAM_CATEGORY_ROBO, + PROGRAM_CATEGORY_SUPL, + PROGRAM_CATEGORY_MISC, + ) /datum/computer_file/program/ntnetdownload/run_program() . = ..() @@ -146,39 +153,29 @@ var/obj/item/computer_hardware/hard_drive/hard_drive = my_computer.all_components[MC_HDD] data["disk_size"] = hard_drive.max_capacity data["disk_used"] = hard_drive.used_capacity - var/list/all_entries[0] - for(var/A in main_repo) - var/datum/computer_file/program/P = A - // Only those programs our user can run will show in the list - if(hard_drive.find_file_by_name(P.filename)) - continue - all_entries.Add(list(list( + data["emagged"] = emagged + + var/list/repo = antag_repo | main_repo + var/list/program_categories = list() + + for(var/I in repo) + var/datum/computer_file/program/P = I + if(!(P.category in program_categories)) + program_categories.Add(P.category) + data["programs"] += list(list( + "icon" = P.program_icon, "filename" = P.filename, "filedesc" = P.filedesc, "fileinfo" = P.extended_desc, - "compatibility" = check_compatibility(P), + "category" = P.category, + "installed" = !!hard_drive.find_file_by_name(P.filename), + "compatible" = check_compatibility(P), "size" = P.size, - "access" = P.can_run(user,transfer = 1, access = access) - ))) - data["hackedavailable"] = FALSE - if(emagged) // If we are running on emagged computer we have access to some "bonus" software - var/list/hacked_programs[0] - for(var/S in antag_repo) - var/datum/computer_file/program/P = S - if(hard_drive.find_file_by_name(P.filename)) - continue - data["hackedavailable"] = TRUE - hacked_programs.Add(list(list( - "filename" = P.filename, - "filedesc" = P.filedesc, - "fileinfo" = P.extended_desc, - "compatibility" = check_compatibility(P), - "size" = P.size, - "access" = TRUE, - ))) - data["hacked_programs"] = hacked_programs + "access" = emagged && P.available_on_syndinet ? TRUE : P.can_run(user,transfer = 1, access = access), + "verifiedsource" = P.available_on_ntnet, + )) - data["downloadable_programs"] = all_entries + data["categories"] = show_categories & program_categories return data @@ -186,8 +183,8 @@ var/hardflag = computer.hardware_flag if(P?.is_supported_by_hardware(hardflag,0)) - return "Compatible" - return "Incompatible!" + return TRUE + return FALSE /datum/computer_file/program/ntnetdownload/kill_program(forced) abort_file_download() diff --git a/code/modules/modular_computers/file_system/programs/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/ntmonitor.dm index b39fcad572d..d508317008a 100644 --- a/code/modules/modular_computers/file_system/programs/ntmonitor.dm +++ b/code/modules/modular_computers/file_system/programs/ntmonitor.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/ntnetmonitor filename = "wirecarp" filedesc = "WireCarp" + category = PROGRAM_CATEGORY_MISC program_icon_state = "comm_monitor" extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes" size = 12 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 19172f130ab..b4e48d0e79a 100644 --- a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/chatclient filename = "ntnrc_client" filedesc = "Chat Client" + category = PROGRAM_CATEGORY_MISC program_icon_state = "command" extended_desc = "This program allows communication over NTNRC network" size = 8 diff --git a/code/modules/modular_computers/file_system/programs/powermonitor.dm b/code/modules/modular_computers/file_system/programs/powermonitor.dm index 78a14ff1ad8..933c9410a27 100644 --- a/code/modules/modular_computers/file_system/programs/powermonitor.dm +++ b/code/modules/modular_computers/file_system/programs/powermonitor.dm @@ -3,6 +3,7 @@ /datum/computer_file/program/power_monitor filename = "ampcheck" filedesc = "AmpCheck" + category = PROGRAM_CATEGORY_ENGI program_icon_state = "power_monitor" extended_desc = "This program connects to sensors around the station to provide information about electrical systems" ui_header = "power_norm.gif" diff --git a/code/modules/modular_computers/file_system/programs/radar.dm b/code/modules/modular_computers/file_system/programs/radar.dm index 9f570fe6a4c..31142b37291 100644 --- a/code/modules/modular_computers/file_system/programs/radar.dm +++ b/code/modules/modular_computers/file_system/programs/radar.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/radar //generic parent that handles most of the process filename = "genericfinder" filedesc = "debug_finder" + category = PROGRAM_CATEGORY_CREW ui_header = "borg_mon.gif" //DEBUG -- new icon before PR program_icon_state = "radarntos" requires_ntnet = TRUE @@ -258,6 +259,7 @@ /datum/computer_file/program/radar/fission360 filename = "fission360" filedesc = "Fission360" + category = PROGRAM_CATEGORY_MISC program_icon_state = "radarsyndicate" extended_desc = "This program allows for tracking of nuclear authorization disks and warheads." requires_ntnet = FALSE diff --git a/code/modules/modular_computers/file_system/programs/robocontrol.dm b/code/modules/modular_computers/file_system/programs/robocontrol.dm index 8c41ea6c380..7fe5a09ab2a 100644 --- a/code/modules/modular_computers/file_system/programs/robocontrol.dm +++ b/code/modules/modular_computers/file_system/programs/robocontrol.dm @@ -2,6 +2,7 @@ /datum/computer_file/program/robocontrol filename = "botkeeper" filedesc = "BotKeeper" + category = PROGRAM_CATEGORY_ROBO program_icon_state = "robot" extended_desc = "A remote controller used for giving basic commands to non-sentient robots." transfer_access = null diff --git a/code/modules/modular_computers/file_system/programs/robotact.dm b/code/modules/modular_computers/file_system/programs/robotact.dm index 34156015ed7..1bb1da54fcd 100644 --- a/code/modules/modular_computers/file_system/programs/robotact.dm +++ b/code/modules/modular_computers/file_system/programs/robotact.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/robotact filename = "robotact" filedesc = "RoboTact" + category = PROGRAM_CATEGORY_ROBO extended_desc = "A built-in app for cyborg self-management and diagnostics." ui_header = "robotact.gif" //DEBUG -- new icon before PR program_icon_state = "command" diff --git a/code/modules/modular_computers/file_system/programs/secureeye.dm b/code/modules/modular_computers/file_system/programs/secureeye.dm index 92275b1e8b6..d2d7590cb18 100644 --- a/code/modules/modular_computers/file_system/programs/secureeye.dm +++ b/code/modules/modular_computers/file_system/programs/secureeye.dm @@ -3,6 +3,7 @@ /datum/computer_file/program/secureye filename = "secureye" filedesc = "SecurEye" + category = PROGRAM_CATEGORY_MISC ui_header = "borg_mon.gif" program_icon_state = "generic" extended_desc = "This program allows access to standard security camera networks." diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm index 799a4eb3ebf..f0ee46e23ae 100644 --- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm @@ -1,6 +1,7 @@ /datum/computer_file/program/supermatter_monitor filename = "ntcims" filedesc = "NT CIMS" + category = PROGRAM_CATEGORY_ENGI ui_header = "smmon_0.gif" program_icon_state = "smmon_0" extended_desc = "Crystal Integrity Monitoring System, connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines." diff --git a/tgui/packages/tgui/interfaces/NtosNetDownloader.js b/tgui/packages/tgui/interfaces/NtosNetDownloader.js index ae9e6b94c75..88e7062a7fb 100644 --- a/tgui/packages/tgui/interfaces/NtosNetDownloader.js +++ b/tgui/packages/tgui/interfaces/NtosNetDownloader.js @@ -1,5 +1,8 @@ -import { useBackend } from '../backend'; -import { Box, Button, Flex, Icon, LabeledList, NoticeBox, ProgressBar, Section } from '../components'; +import { scale, toFixed } from 'common/math'; +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Stack, Icon, LabeledList, NoticeBox, ProgressBar, Section, Tabs } from '../components'; +import { flow } from 'common/fp'; +import { filter, sortBy } from 'common/collections'; import { NtosWindow } from '../layouts'; export const NtosNetDownloader = (props, context) => { @@ -8,16 +11,43 @@ export const NtosNetDownloader = (props, context) => { PC_device_theme, disk_size, disk_used, - downloadable_programs = [], + downloadcompletion, + downloading, + downloadname, + downloadsize, error, - hacked_programs = [], - hackedavailable, + emagged, + categories, + programs, } = data; + const all_categories = ['All'].concat(categories); + const downloadpercentage = toFixed( + scale(downloadcompletion, 0, downloadsize) * 100 + ); + const [ + selectedCategory, + setSelectedCategory, + ] = useLocalState(context, 'category', all_categories[0]); + const items = flow([ + // This filters the list to only contain programs with category + selectedCategory !== all_categories[0] + && filter(program => program.category === selectedCategory), + // This filters the list to only contain verified programs + (!emagged && PC_device_theme === "ntos") + && filter(program => program.verifiedsource === 1), + // This sorts all programs in the lists by name and compatibility + sortBy( + program => -program.compatible, + program => program.filedesc), + ])(programs); + const disk_free_space = downloading + ? disk_size - toFixed(disk_used + downloadcompletion) + : disk_size - disk_used; return ( + width={600} + height={600}> {!!error && ( @@ -31,45 +61,55 @@ export const NtosNetDownloader = (props, context) => { )}
- + + ) || (!!downloadname && ( +
-
- {downloadable_programs - .filter(program => program.access) - .map(program => ( + + + + {all_categories.map(category => ( + setSelectedCategory(category)}> + {category} + + ))} + + + + {items?.map(program => ( ))} - {downloadable_programs - .filter(program => !program.access) - .map(program => ( - - ))} -
- {!!hackedavailable && ( -
- - Please note that Nanotrasen does not recommend download - of software from non-official servers. - - {hacked_programs.map(program => ( - - ))} -
- )} + +
); @@ -79,65 +119,74 @@ const Program = (props, context) => { const { program } = props; const { act, data } = useBackend(context); const { + PC_device_theme, disk_size, disk_used, - downloadcompletion, downloading, downloadname, - downloadsize, + downloadcompletion, } = data; const disk_free = disk_size - disk_used; return ( - - - +
+ + + {program.filedesc} - - + + {program.size} GQ - - - {program.filename === downloadname && ( + + + {(downloading && program.filename === downloadname) && ( ) || ( -
); };