From 3cfde345be128b95c20336d2d557990577b01c6b Mon Sep 17 00:00:00 2001 From: zxaber <37497534+zxaber@users.noreply.github.com> Date: Sun, 3 Nov 2024 22:10:07 -0800 Subject: [PATCH] Removes SiliConnect from borg PDAs, expands their self-status app instead (#87350) ## About The Pull Request - SiliConnect is no longer a default app for cyborgs. - RoboTact, the borg self-status app now has a Network tab, which lists other borgs' status. - The Network tab will only list borgs connected to the same AI as you. If your AI goes down, you lose connection to other borgs' status info. - Your AI is also listed on the Network tab, with their own status in a very binary good/bad form. - Syndicate borgs are able to see other syndicate borgs on the Network list, even though they lack an AI. ## Why It's Good For The Game SiliConnect was recently added to the default borg apps list. But it has a lot of features that borgs can't actually use, and so feels rather messy. It was added with the goal of letting borgs see eachother's status, and so I've ported that functionality into RoboTact. SiliConnect is no longer a default borg app (though it *can* be installed if a borg and human really want it to be). Showing the AI's status is certainly a balance choice. But it's not really that much of a secret when the AI dying already adjusts the monitors across the station to a BSOD image. On the flip side, we get to shut off borg status sharing when the AI goes offline, which is neat. ## Changelog :cl: del: SiliConnect, a tool meant for Roboticists, is no longer included by default on borgs. add: RoboTact, the borg self-status app, now shows the status of other borgs synced to the same AI. Syndicate borgs can likewise see eachother's status, even without an AI. balance: RoboTact also shows their synced AI's very basic status of functional or offline. /:cl: UI Pictures: ![image](https://github.com/user-attachments/assets/1a5b6cbc-daa6-43a7-8ff6-95119d84eb83) Dead AI: ![image](https://github.com/user-attachments/assets/f9f1668c-ae5b-4867-8634-590b573a968c) Syndicate borgs do not see station borg status, but can see eachother's ![image](https://github.com/user-attachments/assets/085a0745-4c18-4a45-bcb4-ef93fa5b799f) ~~Drafting because I need to do edge-case testing, and the AI box isn't quite functioning correctly when the borg has no AI master.~~ --- .../modular_computers/computers/item/pda.dm | 1 - .../file_system/programs/robotact.dm | 48 ++++++- .../packages/tgui/interfaces/NtosRobotact.jsx | 122 +++++++++++++++++- 3 files changed, 167 insertions(+), 4 deletions(-) diff --git a/code/modules/modular_computers/computers/item/pda.dm b/code/modules/modular_computers/computers/item/pda.dm index c375fe9a5c1..1fea772b85e 100644 --- a/code/modules/modular_computers/computers/item/pda.dm +++ b/code/modules/modular_computers/computers/item/pda.dm @@ -328,7 +328,6 @@ starting_programs = list( /datum/computer_file/program/filemanager, /datum/computer_file/program/robotact, - /datum/computer_file/program/borg_monitor, /datum/computer_file/program/atmosscan, /datum/computer_file/program/crew_manifest, ) diff --git a/code/modules/modular_computers/file_system/programs/robotact.dm b/code/modules/modular_computers/file_system/programs/robotact.dm index c213790b80a..927e09c044a 100644 --- a/code/modules/modular_computers/file_system/programs/robotact.dm +++ b/code/modules/modular_computers/file_system/programs/robotact.dm @@ -23,6 +23,20 @@ program_open_overlay = "command-syndicate" return TRUE return FALSE +/** + * Checks if we should see a specific cyborg on our "network". Arguments are our borg, and another borg + * + * Intended to allow borgs with the same AI to see eachother, syndicate borgs (scrambledcodes) with no AI to see eachother + * and not-syndicate borgs with no AI to see no one. Syndicate borgs connected to an AI will no longer see other syndicate + * borgs except ones also slaved to the same AI. + */ +/datum/computer_file/program/robotact/proc/evaluate_borg(mob/living/silicon/robot/this_borg, mob/living/silicon/robot/other_borg) + if(this_borg.connected_ai != other_borg.connected_ai) + return FALSE + if(this_borg.scrambledcodes && other_borg.scrambledcodes) + return TRUE + if(this_borg.connected_ai) + return TRUE /datum/computer_file/program/robotact/ui_data(mob/user) var/list/data = list() @@ -34,9 +48,11 @@ var/mob/living/silicon/robot/cyborg = tablet.silicon_owner - data["name"] = cyborg.name + data["borgName"] = cyborg.name data["designation"] = cyborg.model - data["masterAI"] = cyborg.connected_ai //Master AI + data["masterAI"] = cyborg.connected_ai + data["MasterAI_connected"] = !!cyborg.connected_ai //Need a bool for this on the other side + data["masterAI_online"] = (cyborg.connected_ai?.stat == CONSCIOUS) var/charge = 0 var/maxcharge = 1 @@ -56,6 +72,34 @@ data["thrustersStatus"] = "[cyborg.ionpulse_on?"ACTIVE":"DISABLED"]" //Feedback for thruster status data["selfDestructAble"] = (cyborg.emagged || istype(cyborg, /mob/living/silicon/robot/model/syndicate)) + data["cyborg_groups"] = list() + if(data["masterAI_online"] || (!data["MasterAI_connected"] && cyborg.scrambledcodes)) //If a borg isn't connected, we can just skip this all + var/list/borggroup = list() //temporary list for holding groups of borgs + for(var/mob/living/silicon/robot/other_borg in GLOB.silicon_mobs) + if(!evaluate_borg(cyborg,other_borg)) + continue + + var/shell = FALSE + if(other_borg.shell && !other_borg.ckey) + shell = TRUE + + var/list/cyborg_data = list( + "otherBorgName" = other_borg.name, + "integ" = round((other_borg.health + 100) / 2), //mob heath is -100 to 100, we want to scale that to 0 - 100 + "locked_down" = other_borg.lockcharge, + "status" = other_borg.stat, + "shell_discon" = shell, + "charge" = other_borg.cell ? round(other_borg.cell.percent()) : null, + "module" = other_borg.model ? "[other_borg.model.name]" : "None", + "ref" = REF(other_borg) + ) + borggroup += list(cyborg_data) + if(length(borggroup) == 4) //grouping borgs in packs of four, since I can't do it later in js + data["cyborg_groups"] += list(borggroup) + borggroup = list() + if(length(borggroup)) //and any remainders + data["cyborg_groups"] += list(borggroup) + //Cover, TRUE for locked data["cover"] = "[cyborg.locked? "LOCKED":"UNLOCKED"]" //Ability to move. FAULT if lockdown wire is cut, DISABLED if borg locked, ENABLED otherwise diff --git a/tgui/packages/tgui/interfaces/NtosRobotact.jsx b/tgui/packages/tgui/interfaces/NtosRobotact.jsx index 71afb4db1ba..ecf27b3cf76 100644 --- a/tgui/packages/tgui/interfaces/NtosRobotact.jsx +++ b/tgui/packages/tgui/interfaces/NtosRobotact.jsx @@ -5,11 +5,15 @@ import { AnimatedNumber, Box, Button, + Divider, Flex, LabeledList, + NoticeBox, ProgressBar, Section, Slider, + Stack, + StackDivider, Tabs, } from '../components'; import { formatEnergy } from '../format'; @@ -49,8 +53,11 @@ export const NtosRobotactContent = (props) => { thrustersInstalled, thrustersStatus, selfDestructAble, + cyborg_groups = [], + masterAI_online, + MasterAI_connected, } = data; - const borgName = data.name || []; + const borgName = data.borgName || []; const borgType = data.designation || []; const masterAI = data.masterAI || []; const laws = data.Laws || []; @@ -77,6 +84,14 @@ export const NtosRobotactContent = (props) => { > Logs + setTab_main(3)} + > + Network + {tab_main === 1 && ( @@ -332,6 +347,111 @@ export const NtosRobotactContent = (props) => { )} + {tab_main === 3 && ( + +
+ + + + {!MasterAI_connected + ? 'No Conection' + : masterAI_online + ? 'Online' + : 'Unresponsive'} + + + +
+ + + {cyborg_groups.map((borggroup) => ( + + + {borggroup.map((cyborg) => ( + +
+ + + + {cyborg.status + ? 'Not Responding' + : cyborg.locked_down + ? 'Locked Down' + : cyborg.shell_discon + ? 'Nominal/Disconnected' + : 'Nominal'} + + + + + {cyborg.integ === 0 + ? 'Hard Fault' + : cyborg.integ <= 25 + ? 'Functionality Disrupted' + : cyborg.integ <= 75 + ? 'Functionality Impaired' + : 'Operational'} + + + + + {typeof cyborg.charge === 'number' + ? cyborg.charge + '%' + : 'No Cell'} + + + + {cyborg.module} + + +
+
+ ))} +
+ +
+ ))} +
+ + {!!!cyborg_groups.length && ( + + + CONNECTION UNAVAILABLE -- NETWORK STATUS UNKNOWN + + + )} +
+ )} ); };