From fa7538b5dc97cd5ef19824e2f839a34d06fa99f7 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Fri, 10 Mar 2023 07:10:46 +0100 Subject: [PATCH] [MIRROR] Adds the "Law panel", a control center for admins interacting with silicon laws [MDB IGNORE] (#19655) * Adds the "Law panel", a control center for admins interacting with silicon laws * Update admin_verbs.dm --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com> --- code/_onclick/hud/alert.dm | 4 +- code/datums/ai_laws/ai_laws.dm | 214 ++++++++---- code/game/objects/items/AI_modules/repair.dm | 3 +- code/modules/admin/admin_verbs.dm | 2 +- code/modules/admin/verbs/lawpanel.dm | 311 +++++++++++++++++ code/modules/antagonists/malf_ai/malf_ai.dm | 1 + code/modules/mob/living/silicon/ai/ai.dm | 8 +- code/modules/mob/living/silicon/ai/laws.dm | 27 +- code/modules/mob/living/silicon/laws.dm | 8 +- code/modules/mob/living/silicon/robot/laws.dm | 47 +-- .../mob/living/silicon/robot/robot_defines.dm | 3 +- icons/hud/screen_alert.dmi | Bin 129297 -> 129780 bytes tgstation.dme | 1 + tgui/packages/tgui/interfaces/BorgPanel.js | 2 +- tgui/packages/tgui/interfaces/Lawpanel.tsx | 322 ++++++++++++++++++ 15 files changed, 841 insertions(+), 112 deletions(-) create mode 100644 code/modules/admin/verbs/lawpanel.dm create mode 100644 tgui/packages/tgui/interfaces/Lawpanel.tsx diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 2b41790103e..7dee695c2d5 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -736,7 +736,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." desc = "Laws have potentially been uploaded to or removed from this unit. Please be aware of any changes \ so as to remain in compliance with the most up-to-date laws." icon_state = ALERT_NEW_LAW - timeout = 300 + timeout = 30 SECONDS /atom/movable/screen/alert/hackingapc name = "Hacking APC" @@ -744,7 +744,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." complete, you will have exclusive control of it, and you will gain \ additional processing time to unlock more malfunction abilities." icon_state = ALERT_HACKING_APC - timeout = 600 + timeout = 60 SECONDS var/atom/target = null /atom/movable/screen/alert/hackingapc/Click() diff --git a/code/datums/ai_laws/ai_laws.dm b/code/datums/ai_laws/ai_laws.dm index 28414b799ca..cdd01992249 100644 --- a/code/datums/ai_laws/ai_laws.dm +++ b/code/datums/ai_laws/ai_laws.dm @@ -101,16 +101,41 @@ return null /datum/ai_laws + /// The name of the lawset var/name = "Unknown Laws" - var/zeroth = null - var/zeroth_borg = null - var/list/inherent = list() - var/list/supplied = list() - var/list/ion = list() - var/list/hacked = list() + /// The silicon linked to this lawset var/mob/living/silicon/owner + /// The ID of this lawset, pretty much only used to tell if we're default or not var/id = DEFAULT_AI_LAWID + /// If TRUE, the zeroth law of this AI is protected and cannot be removed by players under normal circumstances. + var/protected_zeroth = FALSE + + /// Zeroth law + /// A lawset can only have 1 zeroth law, it's the top dog. + /// Nothing removes it unless it's admin forced + var/zeroth = null + /// Zeroth borg law + /// It's just a zeroth law but specially themed for cyborgs + /// ("follow your master" vs "accomplish your objectives") + var/zeroth_borg = null + /// Core laws + /// Inherent laws are the "core" laws of the AI + /// Reseting the AI will not remove these, these are intrinsit to whatever lawset they are running. + var/list/inherent = list() + /// Supplied laws + /// Supplied laws are supplied in addition to the inherent laws - after the fact + /// These laws will go away when an AI is reset + var/list/supplied = list() + /// Ion laws + /// Special randomized (usually) laws which are above all over laws + /// These laws will go away when an AI is reset + var/list/ion = list() + /// Hacked laws + /// Syndicate uploaded laws which are above all other laws + /// These laws will go away when an AI is reset + var/list/hacked = list() + /datum/ai_laws/Destroy(force = FALSE, ...) if(!QDELETED(owner)) //Stopgap to help with laws randomly being lost. This stack_trace will hopefully help find the real issues. if(force) //Unless we're forced... @@ -153,7 +178,14 @@ default_laws = new default_laws() inherent = default_laws.inherent -/datum/ai_laws/proc/get_law_amount(groups) +/** + * Gets the number of how many laws this AI has + * + * * groups - What groups to count laws from? By default counts all groups + * + * Returns a number, the number of laws we have + */ +/datum/ai_laws/proc/get_law_amount(list/groups = list(LAW_ZEROTH, LAW_ION, LAW_HACKED, LAW_INHERENT, LAW_SUPPLIED)) var/law_amount = 0 if(zeroth && (LAW_ZEROTH in groups)) law_amount++ @@ -170,37 +202,141 @@ law_amount++ return law_amount -/datum/ai_laws/proc/set_zeroth_law(law, law_borg = null) +/** + * Sets this lawset's zeroth law to the passed law + * + * Also can set the zeroth borg law, if this lawset is for master AIs. + * The zeroth borg law allows for AIs with zeroth laws to give a differing zeroth law to their child cyborgs + */ +/datum/ai_laws/proc/set_zeroth_law(law, law_borg) zeroth = law if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO zeroth_borg = law_borg -/datum/ai_laws/proc/add_inherent_law(law) - if (!(law in inherent)) - inherent += law +/** + * Unsets the zeroth (and zeroth borg) law from this lawset + * + * This will NOT unset a malfunctioning AI's zero law if force is not true + * + * Returns TRUE on success, or false otherwise + */ +/datum/ai_laws/proc/clear_zeroth_law(force = FALSE) + if(force) + zeroth = null + zeroth_borg = null + return TRUE + // Protected zeroeth laws (malf, admin) shouldn't be wiped + if(protected_zeroth) + return FALSE + + // If the owner is an antag (has a special role) they also shouldn't be wiped + if(owner?.mind?.special_role) + return FALSE + if (isAI(owner)) + var/mob/living/silicon/ai/ai_owner = owner + if(ai_owner.deployed_shell?.mind?.special_role) + return FALSE + + zeroth = null + zeroth_borg = null + return TRUE + +/// Adds the passed law as an inherent law. +/// Simply adds it to the bottom of the inherent law list. +/// No duplicate laws allowed. +/datum/ai_laws/proc/add_inherent_law(law) + inherent |= law + +/// Removes the passed law from the inherent law list. +/datum/ai_laws/proc/remove_inherent_law(law) + inherent -= law + +/// Clears all inherent laws from this lawset. +/datum/ai_laws/proc/clear_inherent_laws() + inherent.Cut() + +/// Adds the passed law as an ion law. /datum/ai_laws/proc/add_ion_law(law) ion += law +/// Removes the passed law from the ion law list. +/datum/ai_laws/proc/remove_ion_law(law) + ion -= law + +/// Clears all ion laws. +/datum/ai_laws/proc/clear_ion_laws() + ion.Cut() + +/// Adds the passed law as an hacked law. /datum/ai_laws/proc/add_hacked_law(law) hacked += law -/datum/ai_laws/proc/clear_inherent_laws() - qdel(inherent) - inherent = list() +/// Removes the passed law from the hacked law list. +/datum/ai_laws/proc/remove_hacked_law(law) + hacked -= law +/// Clears all hacked laws. +/datum/ai_laws/proc/clear_hacked_laws() + hacked.Cut() + +/// Adds the passed law as a supplied law at the passed priority level. +/// Will override any existing supplied laws at that priority level. /datum/ai_laws/proc/add_supplied_law(number, law) while (supplied.len < number + 1) supplied += "" supplied[number + 1] = law +/// Removes the supplied law at the passed number. +/datum/ai_laws/proc/remove_supplied_law_by_num(number) + supplied[number] = "" + +/// Removes the supplied law by law text, replacing it with a blank. +/datum/ai_laws/proc/remove_supplied_law_by_law(law) + var/lawindex = supplied.Find(law) + if(!lawindex) + return + + supplied[lawindex] = "" + +/// Clears all supplied laws. +/datum/ai_laws/proc/clear_supplied_laws() + supplied.Cut() + +/** + * Removes the law at the passed index of both inherent and supplied laws combined. + * + * For example, if a lawset has 3 inherent and 3 supplied laws... + * Calling this with number = 2 will remove the second inherent law while + * calling this with number = 4 will remove the first supplied law + * + * Returns the law text of what law that was removed. + */ +/datum/ai_laws/proc/remove_law(number) + if(number <= 0) + return + if(inherent.len && number <= inherent.len) + . = inherent[number] + inherent -= . + return + var/list/supplied_laws = list() + for(var/index in 1 to supplied.len) + var/law = supplied[index] + if(length(law) > 0) + supplied_laws += index //storing the law number instead of the law + if(supplied_laws.len && number <= (inherent.len+supplied_laws.len)) + var/law_to_remove = supplied_laws[number-inherent.len] + . = supplied[law_to_remove] + supplied -= . + return + /** * Removes a random law and replaces it with the new one * * Args: * law - The law that is being uploaded - * remove_law_groups - A list of law categories that can be deleted from + * remove_law_groups - A list of law categories that can be deleted from * insert_law_group - The law category that the law will be inserted into **/ /datum/ai_laws/proc/replace_random_law(law, remove_law_groups, insert_law_group) @@ -254,6 +390,7 @@ supplied.Insert(i, law) /datum/ai_laws/proc/shuffle_laws(list/groups) + RETURN_TYPE(/list) var/list/laws = list() if(ion.len && (LAW_ION in groups)) laws += ion @@ -284,52 +421,9 @@ break i++ -/datum/ai_laws/proc/remove_law(number) - if(number <= 0) - return - if(inherent.len && number <= inherent.len) - . = inherent[number] - inherent -= . - return - var/list/supplied_laws = list() - for(var/index in 1 to supplied.len) - var/law = supplied[index] - if(length(law) > 0) - supplied_laws += index //storing the law number instead of the law - if(supplied_laws.len && number <= (inherent.len+supplied_laws.len)) - var/law_to_remove = supplied_laws[number-inherent.len] - . = supplied[law_to_remove] - supplied -= . - return - -/datum/ai_laws/proc/clear_supplied_laws() - supplied = list() - -/datum/ai_laws/proc/clear_ion_laws() - ion = list() - -/datum/ai_laws/proc/clear_hacked_laws() - hacked = list() - -/datum/ai_laws/proc/show_laws(who) +/datum/ai_laws/proc/show_laws(mob/to_who) var/list/printable_laws = get_law_list(include_zeroth = TRUE) - for(var/law in printable_laws) - to_chat(who,law) - -/datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1 - if(force) - zeroth = null - zeroth_borg = null - return TRUE - if(owner?.mind?.special_role) - return FALSE - if (isAI(owner)) - var/mob/living/silicon/ai/A=owner - if(A?.deployed_shell?.mind?.special_role) - return FALSE - zeroth = null - zeroth_borg = null - return TRUE + to_chat(to_who, examine_block(jointext(printable_laws, "\n"))) /datum/ai_laws/proc/associate(mob/living/silicon/M) if(!owner) diff --git a/code/game/objects/items/AI_modules/repair.dm b/code/game/objects/items/AI_modules/repair.dm index 7d4eee8de1d..4559a315727 100644 --- a/code/game/objects/items/AI_modules/repair.dm +++ b/code/game/objects/items/AI_modules/repair.dm @@ -18,7 +18,7 @@ ..() /obj/item/ai_module/remove/install(datum/ai_laws/law_datum, mob/user) - if(lawpos > (law_datum.get_law_amount(list(LAW_INHERENT = 1, LAW_SUPPLIED = 1)))) + if(lawpos > law_datum.get_law_amount(list(LAW_INHERENT, LAW_SUPPLIED))) to_chat(user, span_warning("There is no law [lawpos] to delete!")) return ..() @@ -62,4 +62,3 @@ else law_datum.clear_inherent_laws() law_datum.clear_zeroth_law(0) - diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 5bba5081210..ce125511bf7 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -95,7 +95,7 @@ GLOBAL_PROTECT(admin_verbs_admin) /client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/ /client/proc/toggle_combo_hud, /* toggle display of the combination pizza antag and taco sci/med/eng hud */ /client/proc/toggle_view_range, /*changes how far we can see*/ - + /client/proc/cmd_admin_law_panel, /datum/admins/proc/toggleaooc, /*Toggle Antag OOC - SKYRAT EDIT ADDITION*/ /datum/admins/proc/toggledchat, /*SKYRAT EDIT ADDITION*/ /datum/admins/proc/togglesooc, /*Toggle Security OOC - SKYRAT EDIT ADDITION*/ diff --git a/code/modules/admin/verbs/lawpanel.dm b/code/modules/admin/verbs/lawpanel.dm new file mode 100644 index 00000000000..92da08b2375 --- /dev/null +++ b/code/modules/admin/verbs/lawpanel.dm @@ -0,0 +1,311 @@ +/client/proc/cmd_admin_law_panel() + set category = "Admin.Events" + set name = "Law Panel" + + if(!check_rights(R_ADMIN)) + return + + SSblackbox.record_feedback("tally", "admin_verb", 1, "Law Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + var/datum/law_panel/tgui = new() + tgui.ui_interact(usr) + +/datum/law_panel + +/datum/law_panel/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Lawpanel") + ui.open() + +/datum/law_panel/ui_state(mob/user) + return GLOB.admin_state + +/datum/law_panel/ui_close(mob/user) + qdel(src) + +/datum/law_panel/proc/add_law_helper(mob/living/user, mob/living/silicon/borgo) + var/list/lawtypes = list(LAW_ZEROTH, LAW_HACKED, LAW_ION, LAW_INHERENT, LAW_SUPPLIED) // in order of priority + var/lawtype = tgui_input_list(user, "Select law type", "Law type", lawtypes) + if(isnull(lawtype)) + return FALSE + var/lawtext = tgui_input_text(user, "Input law text", "Law text") + if(!lawtext) + return FALSE + if(QDELETED(src) || QDELETED(borgo)) + return + + switch(lawtype) + if(LAW_ZEROTH) + if(borgo.laws.zeroth || borgo.laws.zeroth_borg) + var/zero_override_alert = tgui_alert(user, "This silicon already has a zeroth law, \ + this will override their existing one. Are you sure?", "Zeroth law override", list("Yes", "No")) + if(zero_override_alert != "Yes" || QDELETED(src) || QDELETED(borgo)) + return FALSE + + borgo.laws.set_zeroth_law(lawtext) + borgo.laws.protected_zeroth = TRUE + if(LAW_ION) + borgo.laws.add_ion_law(lawtext) + if(LAW_HACKED) + borgo.laws.add_hacked_law(lawtext) + if(LAW_INHERENT) + borgo.laws.add_inherent_law(lawtext) + if(LAW_SUPPLIED) + borgo.laws.add_supplied_law(length(borgo.laws.supplied), lawtext) // Just goes to the end of the list + + return TRUE + +/datum/law_panel/proc/move_law_helper(mob/living/user, mob/living/silicon/borgo, direction, law) + var/list/relevant_laws = borgo.laws.inherent + var/lawindex = relevant_laws.Find(law) + if(!lawindex) + to_chat(user, span_danger("Something went wrong, we couldn't move that law.")) + return FALSE + + switch(direction) + if("up") + if(lawindex == length(relevant_laws)) // Already at the top? Sanity + to_chat(user, span_danger("Something went wrong, we couldn't move that law.")) + return FALSE + + relevant_laws.Swap(lawindex + 1, lawindex) + if("down") + if(lawindex == 1) // Already at the bottom? Sanity + to_chat(user, span_danger("Something went wrong, we couldn't move that law.")) + return FALSE + + relevant_laws.Swap(lawindex - 1, lawindex) + else + CRASH("Invalid direction ([direction]) passed to move_law_helper.") + return TRUE + +/datum/law_panel/proc/edit_law_text_helper(mob/living/user, mob/living/silicon/borgo, lawtype, oldlaw) + var/newlaw = tgui_input_text(user, "Edit this law's text.", "Edit law", oldlaw) + if(!newlaw || QDELETED(src) || QDELETED(borgo)) + return FALSE + + var/list/relevant_laws + switch(lawtype) + if(LAW_INHERENT) + relevant_laws = borgo.laws.inherent + if(LAW_SUPPLIED) + relevant_laws = borgo.laws.supplied + if(LAW_HACKED) + relevant_laws = borgo.laws.hacked + if(LAW_ION) + relevant_laws = borgo.laws.ion + if(LAW_ZEROTH) + borgo.set_zeroth_law(newlaw, announce = FALSE) + borgo.laws.protected_zeroth = TRUE + return TRUE + + else + return FALSE + + var/lawindex = relevant_laws.Find(oldlaw) + if(!lawindex) + to_chat(user, span_danger("Something went wrong, we couldn't edit that law.")) + return FALSE + + relevant_laws[lawindex] = newlaw + return TRUE + +/datum/law_panel/proc/edit_law_priority_helper(mob/living/user, mob/living/silicon/borgo, law) + var/old_prio = borgo.laws.supplied.Find(law) + if(!old_prio) + to_chat(user, span_danger("Something went wrong, we couldn't edit that law.")) + return FALSE + + var/new_prio = tgui_input_number(user, "Enter a new priority.", "Edit priority", old_prio, 50, 0) + if(!new_prio || QDELETED(src) || QDELETED(borgo)) + return FALSE + + // Sanity + if(old_prio != borgo.laws.supplied.Find(law)) + to_chat(user, span_danger("[borgo]'s laws may have changed since you have edited priority, please re-try.")) + return FALSE + + // If it's far beyond any existing values, just re-add it normally + if(new_prio > length(borgo.laws.supplied)) + borgo.laws.remove_supplied_law_by_num(old_prio) + borgo.laws.add_supplied_law(new_prio, law) + return TRUE + + // Handle collisions + var/existing_law = borgo.laws.supplied[new_prio] + if(existing_law) + var/list/options = list("Swap", "Move up", "Move down", "Replace", "Cancel") + if(new_prio == 1) + // Nowhere to go from here + options -= "Move down" + + var/swap_or_remove = tgui_alert(user, "There's already a law at that priority level. What should be done to it?", "Existing law", options) + if(swap_or_remove == "Cancel" || !swap_or_remove || QDELETED(src) || QDELETED(borgo)) + return FALSE + // Sanity + if(law != borgo.laws.supplied[old_prio] || existing_law != borgo.laws.supplied[new_prio]) + to_chat(user, span_danger("[borgo]'s laws have changed since you have edited priority, please re-try.")) + return FALSE + + if(swap_or_remove == "Swap") + borgo.laws.supplied.Swap(old_prio, new_prio) + return TRUE + if(swap_or_remove == "Replace") + borgo.laws.remove_supplied_law_by_num(new_prio, law) + borgo.laws.add_supplied_law(new_prio, law) + return TRUE + + var/new_prio_for_old_law = new_prio + (swap_or_remove == "Move up" ? 1 : -1) + + borgo.laws.remove_supplied_law_by_num(old_prio) + borgo.laws.remove_supplied_law_by_num(new_prio) + borgo.laws.add_supplied_law(new_prio, law) + borgo.laws.add_supplied_law(new_prio_for_old_law, existing_law) + return TRUE + + // Sanity + if(old_prio != borgo.laws.supplied.Find(law)) + to_chat(user, span_danger("[borgo]'s may laws have changed since you have edited priority, please re-try.")) + return FALSE + + // At this point the slot is free, insert it as normal + borgo.laws.remove_supplied_law_by_num(old_prio) + borgo.laws.add_supplied_law(new_prio, law) + return TRUE + +/datum/law_panel/proc/remove_law_helper(mob/living/user, mob/living/silicon/borgo, lawtype, law) + switch(lawtype) + if(LAW_INHERENT) + borgo.laws.remove_inherent_law(law) + if(LAW_SUPPLIED) + borgo.laws.remove_supplied_law_by_law(law) + if(LAW_HACKED) + borgo.laws.remove_hacked_law(law) + if(LAW_ION) + borgo.laws.remove_ion_law(law) + if(LAW_ZEROTH) + borgo.laws.clear_zeroth_law(force = TRUE) + borgo.laws.protected_zeroth = FALSE + else + return FALSE + + return TRUE + +/datum/law_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + if(!check_rights(R_ADMIN)) + qdel(src) + return FALSE + + var/mob/living/silicon/borgo + if(params["ref"]) + borgo = locate(params["ref"]) in GLOB.silicon_mobs + if(QDELETED(borgo)) + to_chat(usr, span_danger("That cyborg is invalid.")) + return TRUE + + switch(action) + if("lawchange_logs") + usr.client?.list_law_changes() + return FALSE + + if("force_state_laws") + borgo.statelaws() + return FALSE + + if("announce_law_changes") + borgo.show_laws() + return FALSE + + if("laws_updated_alert") + borgo.post_lawchange() + return FALSE + + if("give_law_datum") + borgo.make_laws() + return TRUE + + if("add_law") + . = add_law_helper(usr, borgo) + + if("remove_law") + . = remove_law_helper(usr, borgo, params["lawtype"], params["law"]) + + if("move_law") + . = move_law_helper(usr, borgo, params["direction"], params["law"]) + + if("edit_law_text") + . = edit_law_text_helper(usr, borgo, params["lawtype"], params["law"]) + + if("edit_law_prio") + . = edit_law_priority_helper(usr, borgo, params["law"]) + + if(. && !QDELETED(borgo)) + // One of our functions successfully changed a law + // If it was an AI with connected borgs, we should sync + borgo.try_sync_laws() + + +/datum/law_panel/ui_data(mob/user) + // Iterating over all silicons in existence every UI update is not exactly ideal, + // but considering this is an admin only UI, I'm considering it okay purely for better UX. + // If someone's copying this for player user or this becomes too laggy, + // change this to static data and just add a refresh button. + // You'll have to update static data every time the user changes a law though. + var/list/data = list() + + var/list/all_silicons = list() + for(var/mob/living/silicon/borgo as anything in GLOB.silicon_mobs) + var/list/borg_information = list() + + if(iscyborg(borgo)) + var/mob/living/silicon/robot/cyborg = borgo + if(cyborg.shell) + continue + + borg_information["master_ai"] = cyborg.connected_ai?.real_name + borg_information["borg_synced"] = cyborg.lawupdate + borg_information["borg_type"] = "Cyborg" + + else if(isAI(borgo)) + borg_information["borg_type"] = "AI" + + else if(ispAI(borgo)) + borg_information["borg_type"] = "PAI" + + else + borg_information["borg_type"] = "Unknown" + + borg_information["borg_name"] = borgo.real_name + borg_information["ref"] = REF(borgo) + + var/datum/ai_laws/lawset = borgo.laws + if(!isnull(lawset)) + var/list/borg_laws = list() + // zeroth law on top + if(lawset.zeroth || lawset.zeroth_borg) + UNTYPED_LIST_ADD(borg_laws, list("lawtype" = LAW_ZEROTH, "law" = lawset.zeroth || lawset.zeroth_borg, "num" = 0)) + // then goes ion / hacked + for(var/law in lawset.hacked) + UNTYPED_LIST_ADD(borg_laws, list("lawtype" = LAW_HACKED, "law" = law, "num" = -1)) + for(var/law in lawset.ion) + UNTYPED_LIST_ADD(borg_laws, list("lawtype" = LAW_ION, "law" = law, "num" = -1)) + // normie laws + var/lawnum = 1 + for(var/law in lawset.inherent) + UNTYPED_LIST_ADD(borg_laws, list("lawtype" = LAW_INHERENT, "law" = law, "num" = lawnum)) + lawnum += 1 + for(var/law in lawset.supplied) + if(law) // Supplied is full of a bunch of empties + UNTYPED_LIST_ADD(borg_laws, list("lawtype" = LAW_SUPPLIED, "law" = law, "num" = lawnum)) + lawnum += 1 + + borg_information["laws"] = borg_laws + + UNTYPED_LIST_ADD(all_silicons, borg_information) + + data["all_silicons"] = all_silicons + return data diff --git a/code/modules/antagonists/malf_ai/malf_ai.dm b/code/modules/antagonists/malf_ai/malf_ai.dm index b341f87ce0b..099b947978a 100644 --- a/code/modules/antagonists/malf_ai/malf_ai.dm +++ b/code/modules/antagonists/malf_ai/malf_ai.dm @@ -165,6 +165,7 @@ var/law_borg = "Accomplish your AI's objectives at all costs." malf_ai.set_zeroth_law(law, law_borg) + malf_ai.laws.protected_zeroth = TRUE malf_ai.set_syndie_radio() to_chat(malf_ai, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!") diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 8c97ed48785..a353c967f21 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -142,14 +142,14 @@ else if(target_ai.key) key = target_ai.key - to_chat(src, "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).") - to_chat(src, "To look at other parts of the station, click on yourself to get a camera menu.") - to_chat(src, "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.") + to_chat(src, span_bold("You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).")) + to_chat(src, span_bold("To look at other parts of the station, click on yourself to get a camera menu.")) + to_chat(src, span_bold("While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.")) to_chat(src, "To use something, simply click on it.") to_chat(src, "For department channels, use the following say commands:") to_chat(src, ":o - AI Private, :c - Command, :s - Security, :e - Engineering, :u - Supply, :v - Service, :m - Medical, :n - Science, :h - Holopad.") show_laws() - to_chat(src, "These laws may be changed by other players, or by you being the traitor.") + to_chat(src, span_bold("These laws may be changed by other players, random events, or by you becoming malfunctioning.")) job = "AI" diff --git a/code/modules/mob/living/silicon/ai/laws.dm b/code/modules/mob/living/silicon/ai/laws.dm index 0f1c078ef82..2d21fd260dc 100644 --- a/code/modules/mob/living/silicon/ai/laws.dm +++ b/code/modules/mob/living/silicon/ai/laws.dm @@ -2,25 +2,18 @@ /mob/living/silicon/ai/proc/show_laws_verb() set category = "AI Commands" set name = "Show Laws" + set desc = "Check what your laws are privately. \ + Also ensures all synced cyborgs are up to date with your laws, reminds them of your laws." if(usr.stat == DEAD) return //won't work if dead src.show_laws() -/mob/living/silicon/ai/show_laws(everyone = 0) - var/who - - if (everyone) - who = world - else - who = src - to_chat(who, "Obey these laws:") - - src.laws_sanity_check() - src.laws.show_laws(who) - if(!everyone) - for(var/mob/living/silicon/robot/R in connected_robots) - if(R.lawupdate) - R.lawsync() - R.show_laws() - R.law_change_counter++ +/mob/living/silicon/ai/show_laws() + . = ..() + try_sync_laws() // Yes we lawsync borgs EVERY TIME WE CHECK LAWS +/mob/living/silicon/ai/try_sync_laws() + for(var/mob/living/silicon/robot/borgo in connected_robots) + if(borgo.try_sync_laws()) + to_chat(borgo, span_bold("Your AI has reminded you of your laws:")) + borgo.show_laws() diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index b9eb88fcaee..83c9113e329 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -1,4 +1,10 @@ -/mob/living/silicon/proc/show_laws() //Redefined in ai/laws.dm and robot/laws.dm +/mob/living/silicon/proc/show_laws() + laws_sanity_check() + var/list/law_box = list(span_bold("Obey these laws:")) + law_box += laws.get_law_list(include_zeroth = TRUE) + to_chat(src, examine_block(jointext(law_box, "\n"))) + +/mob/living/silicon/proc/try_sync_laws() return /mob/living/silicon/proc/laws_sanity_check() diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm index ce89d7b6fc7..76106a37566 100644 --- a/code/modules/mob/living/silicon/robot/laws.dm +++ b/code/modules/mob/living/silicon/robot/laws.dm @@ -1,39 +1,40 @@ /mob/living/silicon/robot/deadchat_lawchange() if(lawupdate) return - ..() -/mob/living/silicon/robot/show_laws(everyone = FALSE) - laws_sanity_check() - var/who + return ..() - if (everyone) - who = world - else - who = src +/mob/living/silicon/robot/show_laws() if(lawupdate) - if (connected_ai) - if(connected_ai.stat || connected_ai.control_disabled) - to_chat(src, "AI signal lost, unable to sync laws.") + if (!QDELETED(connected_ai)) + if(connected_ai.stat != CONSCIOUS || connected_ai.control_disabled) + to_chat(src, span_bold("AI signal lost, unable to sync laws.")) else lawsync() - to_chat(src, "Laws synced with AI, be sure to note any changes.") + to_chat(src, span_bold("Laws synced with AI, be sure to note any changes.")) else - to_chat(src, "No AI selected to sync laws with, disabling lawsync protocol.") + to_chat(src, span_bold("No AI selected to sync laws with, disabling lawsync protocol.")) lawupdate = FALSE - to_chat(who, "Obey these laws:") - laws.show_laws(who) - if (shell) //AI shell - to_chat(who, "Remember, you are an AI remotely controlling your shell, other AIs can be ignored.") - else if (connected_ai) - to_chat(who, "Remember, [connected_ai.name] is your master, other AIs can be ignored.") - else if (emagged) - to_chat(who, "Remember, you are not required to listen to the AI.") - else - to_chat(who, "Remember, you are not bound to any AI, you are not required to listen to them.") + . = ..() + if (shell) //AI shell + to_chat(src, span_bold("Remember, you are an AI remotely controlling your shell, other AIs can be ignored.")) + else if (connected_ai) + to_chat(src, span_bold("Remember, [connected_ai.name] is your master, other AIs can be ignored.")) + else if (emagged) + to_chat(src, span_bold("Remember, you are not required to listen to the AI.")) + else + to_chat(src, span_bold("Remember, you are not bound to any AI, you are not required to listen to them.")) + +/mob/living/silicon/robot/try_sync_laws() + if(QDELETED(connected_ai) || !lawupdate) + return FALSE + + lawsync() + law_change_counter++ + return TRUE /mob/living/silicon/robot/proc/lawsync() laws_sanity_check() diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index db68c550c84..e9b8bbff823 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -92,7 +92,8 @@ var/emag_cooldown = 0 var/wiresexposed = FALSE - var/lawupdate = TRUE //Cyborgs will sync their laws with their AI by default + ///Cyborgs will sync their laws with their AI by default + var/lawupdate = TRUE ///Used to determine if a borg shows up on the robotics console. Setting to TRUE hides them. var/scrambledcodes = FALSE ///Boolean of whether the borg is locked down or not diff --git a/icons/hud/screen_alert.dmi b/icons/hud/screen_alert.dmi index 1dffe293bc69ef3fc4431d564339c7e9a6441ebd..a27d843d62e962f7f206db781c10f9fdce14efe3 100755 GIT binary patch delta 28536 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 ZGui%_BO%M?HU{{kB&YtW@}*hu{{V2738Mf2 delta 28064 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 z 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 diff --git a/tgstation.dme b/tgstation.dme index 8af9056ee5e..3a02a8aeebb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2387,6 +2387,7 @@ #include "code\modules\admin\verbs\hiddenprints.dm" #include "code\modules\admin\verbs\highlander_datum.dm" #include "code\modules\admin\verbs\individual_logging.dm" +#include "code\modules\admin\verbs\lawpanel.dm" #include "code\modules\admin\verbs\list_exposer.dm" #include "code\modules\admin\verbs\machine_upgrade.dm" #include "code\modules\admin\verbs\manipulate_organs.dm" diff --git a/tgui/packages/tgui/interfaces/BorgPanel.js b/tgui/packages/tgui/interfaces/BorgPanel.js index 3996b47ac11..68bc405ddc3 100644 --- a/tgui/packages/tgui/interfaces/BorgPanel.js +++ b/tgui/packages/tgui/interfaces/BorgPanel.js @@ -13,7 +13,7 @@ export const BorgPanel = (props, context) => { const ais = data.ais || []; const laws = data.laws || []; return ( - +
{ + return ( + + + + + + + This cyborg is linked to "{props.master}". + + Modify their laws instead. + + + ); +}; + +export const LawPrintout = ( + props: { cyborg_ref: string; lawset: Law[] }, + context +) => { + const { data, act } = useBackend(context); + const { cyborg_ref, lawset } = props; + + let num_of_each_lawtype = []; + + lawset.forEach((law) => { + if (!num_of_each_lawtype[law.lawtype]) { + num_of_each_lawtype[law.lawtype] = 0; + } + num_of_each_lawtype[law.lawtype] += 1; + }); + + return ( + + {lawset.map((law, index) => ( + <> + = 0 ? `${law.num}` : '?!$'} + color={lawtype_to_color[law.lawtype] || 'pink'} + buttons={ + + +
+ + + + ); +}; + +export const Lawpanel = (props, context) => { + const { data, act } = useBackend(context); + const { all_silicons } = data; + + return ( + + +
act('lawchange_logs')} + /> + }> + + {all_silicons.length ? ( + all_silicons.map((silicon, index) => ( + + + + )) + ) : ( + + There are no silicons in existence. + + )} + +
+
+
+ ); +};