From ffc6ff07908c180b45df5f4404d0f2779487645f Mon Sep 17 00:00:00 2001 From: Odairu <39929315+Odairu@users.noreply.github.com> Date: Sun, 30 Mar 2025 20:11:25 -0400 Subject: [PATCH] Adds a new station trait Head of Security AI (#3155) ## About The Pull Request This PR adds a new station trait that does the following - Disables HoS as a job - Lowers Security Officer slots from 5 to 2 - Silicons default to Robocop lawset and have access to sec borgs - Similar to AI law divergency, law boards are removed from the upload - The AI is barred from antag status at a code level (this does not stop subversion but it does stop malf) ## Why It's Good For The Game The problem with security borgs was that they would often follow spacelaw instead of their actual laws, it was suggested to me that I make a station trait that puts them on robocop and allows them to pick the model, this has the benefit of making them not available every round, but still available sometimes outside of admin bus. Tweaks and changes for things like how common this trait is can be adjusted in the future of course! ## Proof Of Testing https://github.com/user-attachments/assets/de849f59-517e-4a7b-bc11-79b512142717
Screenshots/Videos
## Changelog :cl: add: adds a new station trait - HoS AI /:cl: --------- Co-authored-by: The Sharkening <95130227+StrangeWeirdKitten@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com> --- .../~~bubber_defines/traits/station_traits.dm | 2 ++ code/datums/ai_laws/ai_laws.dm | 4 ++++ .../objects/items/AI_modules/_AI_modules.dm | 2 +- code/modules/jobs/job_types/cyborg.dm | 2 ++ .../modules/mob/living/silicon/robot/robot.dm | 2 +- .../research/techweb/nodes/robo_nodes.dm | 2 +- .../datums/station_traits/negative_traits.dm | 23 +++++++++++++++++++ tgstation.dme | 2 ++ 8 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 code/__DEFINES/~~bubber_defines/traits/station_traits.dm create mode 100644 modular_zubbers/code/datums/station_traits/negative_traits.dm diff --git a/code/__DEFINES/~~bubber_defines/traits/station_traits.dm b/code/__DEFINES/~~bubber_defines/traits/station_traits.dm new file mode 100644 index 00000000000..35ed04d6cc4 --- /dev/null +++ b/code/__DEFINES/~~bubber_defines/traits/station_traits.dm @@ -0,0 +1,2 @@ +// Enables secborg and puts silicons in control of security +#define STATION_TRAIT_HOS_AI "station_trait_hos_ai" diff --git a/code/datums/ai_laws/ai_laws.dm b/code/datums/ai_laws/ai_laws.dm index b992cb56cd2..3b3848f3bf0 100644 --- a/code/datums/ai_laws/ai_laws.dm +++ b/code/datums/ai_laws/ai_laws.dm @@ -38,6 +38,10 @@ GLOBAL_VAR(round_default_lawset) if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI)) return pick_weighted_lawset() + //Bubber edit start - HoS AI station trait + if(HAS_TRAIT(SSstation, STATION_TRAIT_HOS_AI)) + return /datum/ai_laws/robocop + //Bubber edit end switch(CONFIG_GET(number/default_laws)) if(CONFIG_ASIMOV) diff --git a/code/game/objects/items/AI_modules/_AI_modules.dm b/code/game/objects/items/AI_modules/_AI_modules.dm index 61ca88ee6ce..cf689584805 100644 --- a/code/game/objects/items/AI_modules/_AI_modules.dm +++ b/code/game/objects/items/AI_modules/_AI_modules.dm @@ -23,7 +23,7 @@ /obj/item/ai_module/Initialize(mapload) . = ..() - if(mapload && HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI) && is_station_level(z)) + if(mapload && (HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI) || HAS_TRAIT(SSstation, STATION_TRAIT_HOS_AI)) && is_station_level(z)) //Bubber edit HoS AI station trait var/delete_module = handle_unique_ai() if(delete_module) return INITIALIZE_HINT_QDEL diff --git a/code/modules/jobs/job_types/cyborg.dm b/code/modules/jobs/job_types/cyborg.dm index 81f600347e6..16cd296d263 100644 --- a/code/modules/jobs/job_types/cyborg.dm +++ b/code/modules/jobs/job_types/cyborg.dm @@ -42,6 +42,8 @@ robot_spawn.lawupdate = TRUE robot_spawn.lawsync() robot_spawn.show_laws() + if(HAS_TRAIT(SSstation, STATION_TRAIT_HOS_AI)) + robot_spawn.visible_message(self_message = span_alert("Securityborg has been enabled for this shift.")) //SKYRAT EDIT END if(!robot_spawn.connected_ai) // Only log if there's no Master AI robot_spawn.log_current_laws() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 6c44930b4b8..c2287b0af06 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -178,7 +178,7 @@ ) if(!CONFIG_GET(flag/disable_peaceborg)) GLOB.cyborg_model_list["Peacekeeper"] = /obj/item/robot_model/peacekeeper - if(!CONFIG_GET(flag/disable_secborg)) + if(!CONFIG_GET(flag/disable_secborg) || HAS_TRAIT(SSstation, STATION_TRAIT_HOS_AI)) //Bubber edit HOS AI enable secborg GLOB.cyborg_model_list["Security"] = /obj/item/robot_model/security for(var/model in GLOB.cyborg_model_list) diff --git a/code/modules/research/techweb/nodes/robo_nodes.dm b/code/modules/research/techweb/nodes/robo_nodes.dm index e0e6c5df4b7..40e0ce4067b 100644 --- a/code/modules/research/techweb/nodes/robo_nodes.dm +++ b/code/modules/research/techweb/nodes/robo_nodes.dm @@ -64,7 +64,7 @@ "intellicard", "mecha_tracking_ai_control", ) - else if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI)) + else if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI) || HAS_TRAIT(SSstation, STATION_TRAIT_HOS_AI)) //Bubber edit HoS AI station trait research_costs[TECHWEB_POINT_TYPE_GENERIC] *= 3 /datum/techweb_node/ai_laws diff --git a/modular_zubbers/code/datums/station_traits/negative_traits.dm b/modular_zubbers/code/datums/station_traits/negative_traits.dm new file mode 100644 index 00000000000..017e5f18168 --- /dev/null +++ b/modular_zubbers/code/datums/station_traits/negative_traits.dm @@ -0,0 +1,23 @@ +/datum/station_trait/hos_ai + name = "Head of Security AI" + trait_type = STATION_TRAIT_NEGATIVE + trait_flags = parent_type::trait_flags | STATION_TRAIT_REQUIRES_AI + weight = 3 + show_in_report = TRUE + report_message = "For experimental purposes, this station AI has been put in charge of the security department, Security Cyborgs are enabled for the duration of the shift. \ + Do not meddle with the silicon laws unless absolutely necessary, the AI is to be treated as a member of command, and your head of Security" + blacklist = list(/datum/station_trait/job/human_ai, /datum/station_trait/unique_ai) + trait_to_give = STATION_TRAIT_HOS_AI + +/datum/station_trait/hos_ai/New() + . = ..() + SSstation.antag_restricted_roles += /datum/job/ai::title + +/datum/station_trait/hos_ai/revert() + SSstation.antag_restricted_roles -= /datum/job/ai::title + return ..() + +/datum/station_trait/hos_ai/on_round_start() + . = ..() + for(var/mob/living/silicon/ai/ai as anything in GLOB.ai_list) + ai.show_laws() diff --git a/tgstation.dme b/tgstation.dme index 4eec95a7de9..cb4544e4aa0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -538,6 +538,7 @@ #include "code\__DEFINES\~~bubber_defines\traits\declarations.dm" #include "code\__DEFINES\~~bubber_defines\traits\nanites.dm" #include "code\__DEFINES\~~bubber_defines\traits\sources.dm" +#include "code\__DEFINES\~~bubber_defines\traits\station_traits.dm" #include "code\__HELPERS\_auxtools_api.dm" #include "code\__HELPERS\_dreamluau.dm" #include "code\__HELPERS\_lists.dm" @@ -8872,6 +8873,7 @@ #include "modular_zubbers\code\datums\shuttle\arena.dm" #include "modular_zubbers\code\datums\shuttles\emergency.dm" #include "modular_zubbers\code\datums\station_traits\disabled_traits.dm" +#include "modular_zubbers\code\datums\station_traits\negative_traits.dm" #include "modular_zubbers\code\datums\weather\weather_types\radiation_storm.dm" #include "modular_zubbers\code\datums\weather\weather_types\sand_storm.dm" #include "modular_zubbers\code\datums\wounds\permanent_limp.dm"