diff --git a/README.md b/README.md index 76620835e31..34e5d1c7512 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,9 @@ As of our recent split from Skyrat, a lot of codedocs/modularization guides need **3. Usage of Code Generation Tools** - Usage of autocompletes, auto documentation generation and other tools are allowed -- It is fully expected of a person using any of these tools to ensure the output and quality of said tools -- Any code written by tooling is expected to be heavily tested and proven to work +- It is fully expected of a person using any of these tools to ensure the output and quality of said tools. +- Any code written by tooling is expected to be heavily tested and proven to work. +- AI generation to complete PR bodies, PR comments, or PR reviews is forbidden. Don't have an AI write your pull requests. **4. The Licensing is Non-negotiable** diff --git a/code/__DEFINES/~~bubber_defines/traits/station_traits.dm b/code/__DEFINES/~~bubber_defines/traits/station_traits.dm index 35ed04d6cc4..e380bfe6df7 100644 --- a/code/__DEFINES/~~bubber_defines/traits/station_traits.dm +++ b/code/__DEFINES/~~bubber_defines/traits/station_traits.dm @@ -1,2 +1,4 @@ // Enables secborg and puts silicons in control of security #define STATION_TRAIT_HOS_AI "station_trait_hos_ai" +// Enabled heads of staff to be antags +#define STATION_TRAIT_HEAD_ANTAG "station_trait_head_antag" diff --git a/code/modules/jobs/job_types/security_officer.dm b/code/modules/jobs/job_types/security_officer.dm index 03a8a79891c..18f59a6b9ba 100644 --- a/code/modules/jobs/job_types/security_officer.dm +++ b/code/modules/jobs/job_types/security_officer.dm @@ -320,7 +320,7 @@ GLOBAL_LIST_EMPTY(security_officer_distribution) * This is the function that is responsible for taking the list of preferences, * and spitting out what to put them in. * - * However, it should, wherever possible, prevent solo departments. + * However, it should, wherever possible, prevent solo departments. // BUBBER EDIT: This was patched out, allowing solo departments * That means that if there's one medical officer, and one engineering officer, * that they should be put onto the same department (either medical or engineering). * @@ -463,6 +463,8 @@ GLOBAL_LIST_EMPTY(security_officer_distribution) return selection /proc/get_distribution(candidates, departments) + // BUBBER EDIT BEGIN - REMOVES THE PAIRING CODE. + /* var/number_of_twos = min(departments, round(candidates / 2)) var/redistribute = candidates - (2 * number_of_twos) @@ -471,10 +473,18 @@ GLOBAL_LIST_EMPTY(security_officer_distribution) for (var/index in 1 to number_of_twos) distribution[index] = 2 + */ + var/distribution_size = min(departments, candidates) + var/redistribute = candidates - distribution_size + var/distribution[max(1, distribution_size)] + for (var/index in 1 to distribution_size) + distribution[index] = 1 + for (var/index in 0 to redistribute - 1) distribution[(index % departments) + 1] += 1 return distribution + // BUBBER EDIT END /proc/get_new_officer_distribution_from_late_join( preference, @@ -516,9 +526,13 @@ GLOBAL_LIST_EMPTY(security_officer_distribution) for (var/department in amount_in_departments) var/amount = amount_in_departments[department] + // BUBBER EDIT BEGIN - REMOVES THE PAIRING CODE. + /* if (amount == 1) return department - else if (lowest_amount > amount) + else*/ + if (lowest_amount > amount) + // BUBBER EDIT END lowest_departments = list(department) lowest_amount = amount else if (lowest_amount == amount) diff --git a/code/modules/unit_tests/security_officer_distribution.dm b/code/modules/unit_tests/security_officer_distribution.dm index 05d62eeab35..f6f57474055 100644 --- a/code/modules/unit_tests/security_officer_distribution.dm +++ b/code/modules/unit_tests/security_officer_distribution.dm @@ -6,6 +6,8 @@ "d" = SEC_DEPT_SUPPLY, \ )) +// BUBBER EDIT BEGIN REMOVAL - We don't distribute in a special pairing system +/* /// Test that security officers with specific distributions get their departments. /datum/unit_test/security_officer_roundstart_distribution @@ -106,6 +108,6 @@ test("a", list("a", "a", "b"), "b") test("a", list("a", "a", "b", "b"), "c") test("a", list("a", "a", "b", "b", "c", "c", "d", "d"), "a") - +*/ #undef SECURITY_OFFICER_DEPARTMENTS #undef SECURITY_OFFICER_DEPARTMENTS_TO_NAMES diff --git a/html/changelogs/bubber_archive/2026-08.yml b/html/changelogs/bubber_archive/2026-08.yml index d490a1e0fe6..8c308cc03a5 100644 --- a/html/changelogs/bubber_archive/2026-08.yml +++ b/html/changelogs/bubber_archive/2026-08.yml @@ -115,3 +115,13 @@ - rscadd: New Tarkon borgs, jack of all trades Odairu: - qol: Hydra allows for a unique whole name, and choosable head names +2026-08-11: + Maia-J: + - balance: Sec officers no longer get forced into a department with another officer + when an empty department is available, making the dept preference system make + sense. +2026-08-12: + CentralSmith: + - bugfix: Mr. Fluff now recognises his owner and responds to pet commands. + Odairu: + - rscadd: a station trait that allows heads of staff to be antags diff --git a/modular_zubbers/code/datums/station_traits/negative_traits.dm b/modular_zubbers/code/datums/station_traits/negative_traits.dm index 527486dd154..8cc0bfade32 100644 --- a/modular_zubbers/code/datums/station_traits/negative_traits.dm +++ b/modular_zubbers/code/datums/station_traits/negative_traits.dm @@ -21,3 +21,12 @@ . = ..() for(var/mob/living/silicon/ai/ai as anything in GLOB.ai_list) ai.show_laws() + +///Another potentially bad idea to fit in this file (I'm full of these) +/datum/station_trait/head_antags + name = "Background check budget cuts" + trait_type = STATION_TRAIT_NEGATIVE + trait_flags = parent_type::trait_flags + weight = 3 + show_in_report = FALSE + trait_to_give = STATION_TRAIT_HEAD_ANTAG diff --git a/modular_zubbers/code/modules/loadout/categories/inhands.dm b/modular_zubbers/code/modules/loadout/categories/inhands.dm index 6157434baeb..cc2869b6314 100644 --- a/modular_zubbers/code/modules/loadout/categories/inhands.dm +++ b/modular_zubbers/code/modules/loadout/categories/inhands.dm @@ -12,6 +12,17 @@ /datum/loadout_item/inhand/pet/mrfluff_mothroach name = "Mr. Fluff" item_path = /obj/item/mob_holder/pet/donator/centralsmith + ckeywhitelist = list("centralsmith") + +/// ckeywhitelist above means only I can take him, so befriending whoever equips him is safe. +/datum/loadout_item/inhand/pet/mrfluff_mothroach/on_equip_item(obj/item/equipped_item, list/item_details, mob/living/carbon/human/equipper, datum/outfit/outfit, visuals_only = FALSE) + . = ..() + if(visuals_only) + return + var/obj/item/mob_holder/pet/holder = equipped_item + if(!istype(holder) || isnull(holder.held_mob)) + return + holder.held_mob.befriend(equipper) /datum/loadout_item/inhand/saddlebags name = "Saddlebags" diff --git a/modular_zubbers/code/modules/storyteller/event_defines/crewset/_antagonist_event.dm b/modular_zubbers/code/modules/storyteller/event_defines/crewset/_antagonist_event.dm index 2ff1eca2d0f..0f0cf2bb4b1 100644 --- a/modular_zubbers/code/modules/storyteller/event_defines/crewset/_antagonist_event.dm +++ b/modular_zubbers/code/modules/storyteller/event_defines/crewset/_antagonist_event.dm @@ -84,6 +84,14 @@ /datum/round_event_control/antagonist/proc/get_candidates() var/round_started = SSticker.HasRoundStarted() + if(HAS_TRAIT(SSstation, STATION_TRAIT_HEAD_ANTAG)) + restricted_roles -= list( + JOB_HEAD_OF_PERSONNEL, + JOB_CHIEF_ENGINEER, + JOB_CHIEF_MEDICAL_OFFICER, + JOB_RESEARCH_DIRECTOR, + JOB_QUARTERMASTER, + ) var/list/candidates = SSgamemode.get_candidates(antag_flag, pick_roundstart_players = !round_started, restricted_roles = restricted_roles, restricted_species = restricted_species) return candidates