From 6808a082ebb50fc149a60af0e719d20bb6fb1295 Mon Sep 17 00:00:00 2001 From: Timberpoes Date: Fri, 13 Sep 2024 12:58:35 +0100 Subject: [PATCH] =?UTF-8?q?Assorted=20changes=20to=20job=20assignment=20co?= =?UTF-8?q?de=20and=20logging.=20Runtime=20free,=20guaranteed=20or=20your?= =?UTF-8?q?=20money=20back.=20Price:=20$=C2=A30.=20(#85947)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## About The Previous Pull Request #85308 reverted by #85929 ![image](https://github.com/user-attachments/assets/e7518dcb-a60a-4bf1-a3d4-a5a8966d8633) ~~Causes the round to not start when a player isn't eligible for any jobs at a specific priority level due to runtimes trying to `pick()` from an empty list aborting the entire job assignment stack.~~ (Fixed???? by https://github.com/tgstation/tgstation/pull/85947/commits/e0e9f2f430079d4ab7097abe12e75f934131a638) Maybe we should test merge this for a mo just to make sure no more cheeky runtimes pop up before merging. ## About The Pull Request This PR does a couple of minor things: Makes the job debug logging a bit easier to follow. Minorly brings some SSjob code up to code standards, converting proc names to snake_case and doing some otherm is cleanup. Refactored some stuff into different procs, updated some comments. And some major things: Changes the job assignment logic. Old behaviour > Assign dynamic priority roles > Force one Head of Staff (if possible) > Assign all AIs > Assign overflow roles (bugged in 2 ways) > Shuffle the available jobs list once, at the start of the random job assignment loop > Pick and assign random jobs for random players from High prefs down, with a priority on Head of Staff roles > Handle everyone that couldn't be assigned a random job New behaviour > Assign dynamic priority roles > Assign all Head of Staff roles to players with High prefs > If no Head of Staff was made in the above way, force one Head of Staff (if possible) > Assign all AIs > Assign overflow roles (fixed) > Prioritise and fill unfilled head roles at each job priority pref level, from High prefs down. > Build a list of all jobs that each unassigned player could be eligible for at the above pref level. > Pick a job from that list at random and assign it to the player. > Handle everyone that couldn't be assigned a random job. In reality there should be little impact on overall job assignment, the code changes read more as semantics. For example, the priority check for filling Head slots will have the same candidate pool in both old and new versions, but in the new version we're more clearly saying that Heads are important and we want to prioritise filling them for the sake of round progression even though the outcome in new and old is the same. A key change will lead to an increase in assistants - Overflow fixes. Currently the code block to do early assignments to the Overflow role doesn't work - or works but not as you'd expect. The idea was is that because enabling the Overflow role in the prefs menu is an On/Off toggle that sets the job to High priority when enabled and prevents any other High priority pref, players that have the Overflow role enabled will **always** get it. It's their highest priority job with infinite slots. So we do a pass right at the start to give everyone with the Overflow role enabled that role and save us wasting time later on in random job code giving them that same role but with more work. The problem is the code for this only assigns the Overflow role to people with it set to Low priority in their prefs, resulting in log readouts like: ``` [2024-07-27 09:49:43.469] DEBUG-JOB: DO, Running Overflow Check 1 [2024-07-27 09:49:43.469] DEBUG-JOB: Running FOC, Job: /datum/job/assistant, Level: Low Priority [2024-07-27 09:49:43.472] DEBUG-JOB: FOC player job enabled at wrong level, Player: Radioprague, TheirLevel: Medium Priority, ReqLevel: Low Priority [2024-07-27 09:49:43.472] DEBUG-JOB: FOC player job enabled at wrong level, Player: Caluan, TheirLevel: High Priority, ReqLevel: Low Priority [2024-07-27 09:49:43.473] DEBUG-JOB: FOC player job enabled at wrong level, Player: Caractaser, TheirLevel: High Priority, ReqLevel: Low Priority [2024-07-27 09:49:43.473] DEBUG-JOB: FOC player job enabled at wrong level, Player: Apsua, TheirLevel: High Priority, ReqLevel: Low Priority [2024-07-27 09:49:43.475] DEBUG-JOB: FOC player job enabled at wrong level, Player: Bebrus2, TheirLevel: Medium Priority, ReqLevel: Low Priority [2024-07-27 09:49:43.475] DEBUG-JOB: AC1, Candidates: 0 ``` Where nobody gets pre-assigned the overflow role because their prefs are all set to the High priority from being toggled... Except wait a second, some people have it at Medium priority when it should just be a No Role/High Priority Role toggle? And herein we meet a problem. My hypothesis is that traits and stuff that change the overflow have allowed players to set the "ordinary" overflow role of Assistant to Medium and/or Low priority. This still shows as enabled in the prefs menu, but leads to an outcome where a player with assistant enabled is assigned Cook instead. ``` [2024-07-27 09:49:47.775] DEBUG-JOB: DO, Running Overflow Check 1 [2024-07-27 09:49:47.775] DEBUG-JOB: Running FOC, Job: /datum/job/assistant, Level: Low Priority ... [2024-07-27 09:49:43.475] DEBUG-JOB: FOC player job enabled at wrong level, Player: Bebrus2, TheirLevel: Medium Priority, ReqLevel: Low Priority ... [2024-07-27 09:49:47.987] DEBUG-JOB: Running AR, Player: Bebrus2, Job: /datum/job/cook, LateJoin: 0 ``` So players with the Overflow job pref set to Low (an unexpected state, should be disabled or High) would be guaranteed to get that role if none of the higher priority Head of Staff/AI/Dynamic roles took over via the bugged "force overflow for people with the pref enabled" proc. Players with the Overflow job pref set to High would be guaranteed to get that role if none of the higher priority Head of Staff/AI/Dynamic roles took over via the random job assignment code giving them their Highest priority role thanks to the infinite job slots of the Overflow. And players with the Overflow job pref set to Medium (an unexpected state, should be disabled or High) would get Assistant if the shuffle step of the available jobs list put Assisstant before any of the other jobs they had prefs enabled for at Medium that weren't already filled, otherwise they'd get another random job. This code is now changed to ignore the priority the player has set when looking for people to fill the overflow role. As long as it **is** enabled, the player will get it unless they're forced into a dynamic ruleset role (AI when malf rolls) or a Head of Staff role due to their other prefs (they have RD set to med or low, and no other player has a Head of Staff at high so they get randomly picked and miss the overflow role). This will increase the number of assistants in shifts where their pref state has Assisstant in the bugged Medium priority, but doesn't change it for bugged Low and not-bugged High/On priority. On the other side of the coin, we have how the random jobs are picked. They're kinda not random, and I noticed this reading the logs then reading the code. The list of available jobs to pick from is randomly shuffled - but only **once**. All players pull from a list of jobs in the same order. So you end up with a log block like this: ``` [2024-07-27 09:49:47.985] DEBUG-JOB: DO pass, Player: Pierow, Level:3, Job:Botanist [2024-07-27 09:49:47.985] DEBUG-JOB: Running AR, Player: Pierow, Job: /datum/job/botanist, LateJoin: 0 [2024-07-27 09:49:47.985] DEBUG-JOB: Player: Pierow is now Rank: Botanist, JCP:0, JPL:2 [2024-07-27 09:49:47.986] DEBUG-JOB: DO pass, Player: Daddos, Level:3, Job:Botanist [2024-07-27 09:49:47.986] DEBUG-JOB: Running AR, Player: Daddos, Job: /datum/job/botanist, LateJoin: 0 [2024-07-27 09:49:47.986] DEBUG-JOB: Player: Daddos is now Rank: Botanist, JCP:1, JPL:2 [2024-07-27 09:49:47.986] DEBUG-JOB: FOC job filled and not overflow, Player: Bebrus2, Job: /datum/job/botanist, Current: 2, Limit: 2 [2024-07-27 09:49:47.987] DEBUG-JOB: FOC player job not enabled, Player: Bebrus2 [2024-07-27 09:49:47.987] DEBUG-JOB: DO pass, Player: Bebrus2, Level:3, Job:Cook [2024-07-27 09:49:47.987] DEBUG-JOB: Running AR, Player: Bebrus2, Job: /datum/job/cook, LateJoin: 0 [2024-07-27 09:49:47.988] DEBUG-JOB: Player: Bebrus2 is now Rank: Cook, JCP:0, JPL:1 [2024-07-27 09:49:47.988] DEBUG-JOB: FOC player job not enabled, Player: Redwizz [2024-07-27 09:49:47.988] DEBUG-JOB: FOC job filled and not overflow, Player: Redwizz, Job: /datum/job/cook, Current: 1, Limit: 1 ``` The list is shuffled into an order of something like `list("Scientist", "Botanist", "Cook", "Sec Officer", ...)` then iterated over for each player. So every random job selection goes: > "Does Player1 have Scientist enabled and at the right priority? No? Okay, Botanist? Yes? You get botanist." > "Does Player2 have Scientist enabled and at the right priority? No? Okay, Botanist? Yes? You get botanist." > "Does Player3 have Scientist enabled and at the right priority? No? Okay, Botanist has no slots left so we'll remove it from the list. Okay, Cook? Yes? You get cook." > "Does Player4 have Scientist enabled and at the right priority? No? Okay, Cook has no slots left so we'll remove it from the list. Okay, Sec Officer? ..." This can lead to stacked individual departments if it gets randomly rolled to the start of the list in the shuffle, and completely empty departments if they end up at the end. On high pop shifts this is probably less of an issue. Player prefs add noise to this and as departments at the front fill up, those at the back pick up some of the lower pref players. But have you ever had a shift where there's just like... No fucking sec even though there's tons of players? The logging (before I made changes in this PR) was a bit ass, but my hypothesis there is that sec officer was shuffled right at the end of the random job list, so every other department was filled up before sec officers were picked. To mitigate this, I made the list shuffle every single time the game picks a random available job for the player. This should lead to a more balanced selection of available jobs by avoiding situations where the code is biased towards packing some departments by accident. ## Why It's Good For The Game Overflow fixes mean people who go to their prefs and see the Overflow Role is On will all have the same experience - They will be the Overflow role. More random random job selection should prevent individual departments having a jobs be stacked when it would have otherwise been possible for a more balanced selection but the code unintentially biased random departments to be overstaffed and understaffed each shift. ## Changelog :cl: fix: Having the Overflow Role set to On will properly ensure you get that role at a High priority as intended by the game code. fix: Job selection is now a little bit more random. Fixes an unintentional bias in random job assignment that could lead to feast-or-famine for roles where everyone is assigned one job and nobody is assigned another job. /:cl: --- .../dcs/signals/signals_global_object.dm | 4 +- .../signals/signals_mob/signals_mob_carbon.dm | 2 +- code/__DEFINES/jobs.dm | 2 +- code/__DEFINES/preferences.dm | 1 + code/__HELPERS/game.dm | 2 +- code/controllers/subsystem/dynamic/dynamic.dm | 6 +- .../subsystem/dynamic/dynamic_rulesets.dm | 2 +- .../dynamic/dynamic_rulesets_midround.dm | 6 +- .../dynamic/dynamic_rulesets_roundstart.dm | 8 +- code/controllers/subsystem/job.dm | 420 ++++++++++-------- code/controllers/subsystem/ticker.dm | 6 +- code/datums/ai_laws/ai_laws.dm | 2 +- code/datums/brain_damage/imaginary_friend.dm | 4 +- code/datums/elements/art.dm | 2 +- code/datums/id_trim/jobs.dm | 4 +- code/datums/mind/_mind.dm | 4 +- code/datums/mind/antag.dm | 2 +- code/datums/mind/initialization.dm | 6 +- code/datums/records/manifest.dm | 2 +- code/datums/station_traits/job_traits.dm | 4 +- .../machinery/porta_turret/portable_turret.dm | 2 +- code/game/objects/items/cards_ids.dm | 4 +- code/modules/admin/admin_verbs.dm | 6 +- code/modules/admin/verbs/admin.dm | 2 +- code/modules/admin/verbs/admingame.dm | 10 +- code/modules/admin/verbs/ai_triumvirate.dm | 2 +- code/modules/admin/verbs/ert.dm | 2 +- code/modules/admin/verbs/secrets.dm | 2 +- .../antagonists/_common/antag_spawner.dm | 2 +- code/modules/antagonists/abductor/abductor.dm | 2 +- .../abductor/machinery/experiment.dm | 2 +- code/modules/antagonists/clown_ops/clownop.dm | 2 +- .../antagonists/nukeop/datums/operative.dm | 2 +- .../paradox_clone/paradox_clone.dm | 2 +- .../antagonists/space_dragon/space_dragon.dm | 4 +- .../antagonists/space_ninja/space_ninja.dm | 4 +- code/modules/antagonists/wizard/wizard.dm | 2 +- code/modules/antagonists/xeno/xeno.dm | 4 +- code/modules/bitrunning/server/threats.dm | 2 +- code/modules/client/preferences.dm | 2 +- .../client/preferences/middleware/jobs.dm | 2 +- .../preferences/species_features/vampire.dm | 2 +- .../clothing/chameleon/_chameleon_action.dm | 2 +- code/modules/clothing/outfits/event.dm | 2 +- .../events/ghost_role/fugitive_event.dm | 2 +- code/modules/events/ghost_role/morph_event.dm | 2 +- code/modules/events/ghost_role/nightmare.dm | 2 +- code/modules/events/ghost_role/operative.dm | 2 +- code/modules/events/wizard/rpgtitles.dm | 2 +- code/modules/jobs/job_types/_job.dm | 4 +- code/modules/jobs/job_types/cook.dm | 2 +- .../modules/mob/dead/new_player/new_player.dm | 8 +- .../mob/dead/new_player/preferences_setup.dm | 4 +- .../living/basic/space_fauna/demon/demon.dm | 2 +- .../basic/space_fauna/revenant/_revenant.dm | 2 +- code/modules/mob/living/brain/posibrain.dm | 4 +- .../mob/living/carbon/human/human_helpers.dm | 2 +- code/modules/mob/living/silicon/ai/ai.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 2 +- .../hostile/megafauna/colossus.dm | 2 +- .../mob_spawn/ghost_roles/unused_roles.dm | 2 +- code/modules/mob_spawn/mob_spawn.dm | 2 +- .../file_system/programs/jobmanagement.dm | 6 +- .../spells/spell_types/self/mime_vow.dm | 2 +- code/modules/unit_tests/anonymous_themes.dm | 2 +- code/modules/unit_tests/dummy_spawn.dm | 2 +- .../security_officer_distribution.dm | 2 +- code/modules/unit_tests/traitor.dm | 2 +- .../unit_tests/traitor_mail_content_check.dm | 2 +- 69 files changed, 328 insertions(+), 295 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_global_object.dm b/code/__DEFINES/dcs/signals/signals_global_object.dm index bed06ff176c..d100f47a3c9 100644 --- a/code/__DEFINES/dcs/signals/signals_global_object.dm +++ b/code/__DEFINES/dcs/signals/signals_global_object.dm @@ -1,9 +1,9 @@ /// signals from globally accessible objects -///from SSJob whenever SetupOccupations() is called, all occupations are set +///from SSJob whenever setup_occupations() is called, all occupations are set #define COMSIG_OCCUPATIONS_SETUP "occupations_setup" -///from SSJob when DivideOccupations is called +///from SSJob when divide_occupations() is called #define COMSIG_OCCUPATIONS_DIVIDED "occupations_divided" ///from SSsun when the sun changes position : (azimuth) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index 56d5ddf4524..b95ffba607f 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -118,7 +118,7 @@ ///Applied preferences to a human #define COMSIG_HUMAN_PREFS_APPLIED "human_prefs_applied" -///Whenever EquipRanked is called, called after job is set +///Whenever equip_rank is called, called after job is set #define COMSIG_JOB_RECEIVED "job_received" ///from /mob/living/carbon/human/proc/set_coretemperature(): (oldvalue, newvalue) #define COMSIG_HUMAN_CORETEMP_CHANGE "human_coretemp_change" diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index d63efd92445..953e7648009 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -205,7 +205,7 @@ DEFINE_BITFIELD(departments_bitflags, list( #define JOB_ANNOUNCE_ARRIVAL (1<<0) /// Whether the mob is added to the crew manifest. #define JOB_CREW_MANIFEST (1<<1) -/// Whether the mob is equipped through SSjob.EquipRank() on spawn. +/// Whether the mob is equipped through SSjob.equip_rank() on spawn. #define JOB_EQUIP_RANK (1<<2) /// Whether the job is considered a regular crew member of the station. Equipment such as AI and cyborgs not included. #define JOB_CREW_MEMBER (1<<3) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index d6b62da97d4..5fb9d9447bb 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -80,6 +80,7 @@ //Job preferences levels +#define JP_ANY 0 #define JP_LOW 1 #define JP_MEDIUM 2 #define JP_HIGH 3 diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index ce48e593980..c68b450c2c2 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -181,7 +181,7 @@ //First we spawn a dude. var/mob/living/carbon/human/new_character = new//The mob being spawned. - SSjob.SendToLateJoin(new_character) + SSjob.send_to_late_join(new_character) ghost_player.client.prefs.safe_transfer_prefs_to(new_character) new_character.dna.update_dna_identity() diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index 2092b3efacd..c3edc30dc68 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -526,7 +526,7 @@ SUBSYSTEM_DEF(dynamic) //To new_player and such, and we want the datums to just free when the roundstart work is done var/list/roundstart_rules = init_rulesets(/datum/dynamic_ruleset/roundstart) - SSjob.DivideOccupations(pure = TRUE, allow_all = TRUE) + SSjob.divide_occupations(pure = TRUE, allow_all = TRUE) for(var/i in GLOB.new_player_list) var/mob/dead/new_player/player = i if(player.ready == PLAYER_READY_TO_PLAY && player.mind && player.check_preferences()) @@ -541,7 +541,7 @@ SUBSYSTEM_DEF(dynamic) else roundstart_pop_ready++ candidates.Add(player) - SSjob.ResetOccupations() + SSjob.reset_occupations() log_dynamic("Listing [roundstart_rules.len] round start rulesets, and [candidates.len] players ready.") if (candidates.len <= 0) log_dynamic("[candidates.len] candidates.") @@ -1018,7 +1018,7 @@ SUBSYSTEM_DEF(dynamic) var/list/reopened_jobs = list() for(var/mob/living/quitter in GLOB.suicided_mob_list) - var/datum/job/job = SSjob.GetJob(quitter.job) + var/datum/job/job = SSjob.get_job(quitter.job) if(!job || !(job.job_flags & JOB_REOPEN_ON_ROUNDSTART_LOSS)) continue if(!include_command && job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets.dm index c77cce50d01..0d3242a4d17 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets.dm @@ -283,7 +283,7 @@ if(length(exclusive_roles)) var/exclusive_candidate = FALSE for(var/role in exclusive_roles) - var/datum/job/job = SSjob.GetJob(role) + var/datum/job/job = SSjob.get_job(role) if((role in candidate_client.prefs.job_preferences) && SSjob.check_job_eligibility(candidate_player, job, "Dynamic Roundstart TC", add_job_to_log = TRUE) == JOB_AVAILABLE) exclusive_candidate = TRUE diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm index 3476702e741..efe857b936d 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm @@ -413,7 +413,7 @@ return ..() /datum/dynamic_ruleset/midround/from_ghosts/nuclear/finish_setup(mob/new_character, index) - new_character.mind.set_assigned_role(SSjob.GetJobType(/datum/job/nuclear_operative)) + new_character.mind.set_assigned_role(SSjob.get_job_type(/datum/job/nuclear_operative)) new_character.mind.special_role = ROLE_NUCLEAR_OPERATIVE if(index == 1) var/datum/antagonist/nukeop/leader/leader_antag_datum = new() @@ -572,7 +572,7 @@ var/mob/living/carbon/human/new_nightmare = new (find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = TRUE)) player_mind.transfer_to(new_nightmare) - player_mind.set_assigned_role(SSjob.GetJobType(/datum/job/nightmare)) + player_mind.set_assigned_role(SSjob.get_job_type(/datum/job/nightmare)) player_mind.special_role = ROLE_NIGHTMARE player_mind.add_antag_datum(/datum/antagonist/nightmare) new_nightmare.set_species(/datum/species/shadow/nightmare) @@ -991,7 +991,7 @@ var/mob/living/carbon/human/voidwalker = new (space_turf) player_mind.transfer_to(voidwalker) - player_mind.set_assigned_role(SSjob.GetJobType(/datum/job/voidwalker)) + player_mind.set_assigned_role(SSjob.get_job_type(/datum/job/voidwalker)) player_mind.special_role = antag_flag player_mind.add_antag_datum(antag_datum) diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm index 999cd156b18..79eedc0adb8 100644 --- a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm @@ -63,7 +63,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) flags = HIGH_IMPACT_RULESET /datum/dynamic_ruleset/roundstart/malf_ai/ready(forced) - var/datum/job/ai_job = SSjob.GetJobType(/datum/job/ai) + var/datum/job/ai_job = SSjob.get_job_type(/datum/job/ai) // If we're not forced, we're going to make sure we can actually have an AI in this shift, if(!forced && min(ai_job.total_positions - ai_job.current_positions, ai_job.spawn_positions) <= 0) @@ -75,7 +75,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) /datum/dynamic_ruleset/roundstart/malf_ai/pre_execute(population) . = ..() - var/datum/job/ai_job = SSjob.GetJobType(/datum/job/ai) + var/datum/job/ai_job = SSjob.get_job_type(/datum/job/ai) // Maybe a bit too pedantic, but there should never be more malf AIs than there are available positions, spawn positions or antag cap allocations. var/num_malf = min(get_antag_cap(population), min(ai_job.total_positions - ai_job.current_positions, ai_job.spawn_positions)) for (var/i in 1 to num_malf) @@ -296,7 +296,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) var/mob/M = pick_n_take(candidates) if (M) assigned += M.mind - M.mind.set_assigned_role(SSjob.GetJobType(/datum/job/space_wizard)) + M.mind.set_assigned_role(SSjob.get_job_type(/datum/job/space_wizard)) M.mind.special_role = ROLE_WIZARD return TRUE @@ -429,7 +429,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE) break var/mob/M = pick_n_take(candidates) assigned += M.mind - M.mind.set_assigned_role(SSjob.GetJobType(job_type)) + M.mind.set_assigned_role(SSjob.get_job_type(job_type)) M.mind.special_role = required_role return TRUE diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index b1629237dc6..0b04b25c597 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -22,7 +22,7 @@ SUBSYSTEM_DEF(job) var/list/unassigned = list() //Players who need jobs var/initial_players_to_assign = 0 //used for checking against population caps - // Whether to run DivideOccupations pure so that there are no side-effects from calling it other than + // Whether to run divide_occupations pure so that there are no side-effects from calling it other than // a player's assigned_role being set to some value. var/run_divide_occupation_pure = FALSE @@ -31,7 +31,7 @@ SUBSYSTEM_DEF(job) var/overflow_role = /datum/job/assistant - var/list/level_order = list(JP_HIGH,JP_MEDIUM,JP_LOW) + var/list/level_order = list(JP_HIGH, JP_MEDIUM, JP_LOW) /// Lazylist of mob:occupation_string pairs. var/list/dynamic_forced_occupations @@ -88,7 +88,7 @@ SUBSYSTEM_DEF(job) setup_job_lists() job_config_datum_singletons = generate_config_singletons() // we set this up here regardless in case someone wants to use the verb to generate the config file. if(!length(all_occupations)) - SetupOccupations() + setup_occupations() if(CONFIG_GET(flag/load_jobs_from_txt)) load_jobs_from_config() set_overflow_role(CONFIG_GET(string/overflow_job)) // this must always go after load_jobs_from_config() due to how the legacy systems operate, this always takes precedent. @@ -108,9 +108,9 @@ SUBSYSTEM_DEF(job) return overflow_jobs /datum/controller/subsystem/job/proc/set_overflow_role(new_overflow_role) - var/datum/job/new_overflow = ispath(new_overflow_role) ? GetJobType(new_overflow_role) : GetJob(new_overflow_role) + var/datum/job/new_overflow = ispath(new_overflow_role) ? get_job_type(new_overflow_role) : get_job(new_overflow_role) if(!new_overflow) - JobDebug("Failed to set new overflow role: [new_overflow_role]") + job_debug("SET_OVRFLW: Failed to set new overflow role: [new_overflow_role]") CRASH("set_overflow_role failed | new_overflow_role: [isnull(new_overflow_role) ? "null" : new_overflow_role]") var/cap = CONFIG_GET(number/overflow_cap) @@ -121,17 +121,16 @@ SUBSYSTEM_DEF(job) if(new_overflow.type == overflow_role) return - var/datum/job/old_overflow = GetJobType(overflow_role) + var/datum/job/old_overflow = get_job_type(overflow_role) old_overflow.allow_bureaucratic_error = initial(old_overflow.allow_bureaucratic_error) old_overflow.spawn_positions = initial(old_overflow.spawn_positions) old_overflow.total_positions = initial(old_overflow.total_positions) if(!(initial(old_overflow.job_flags) & JOB_CANNOT_OPEN_SLOTS)) old_overflow.job_flags &= ~JOB_CANNOT_OPEN_SLOTS overflow_role = new_overflow.type - JobDebug("Overflow role set to : [new_overflow.type]") + job_debug("SET_OVRFLW: Overflow role set to: [new_overflow.type]") - -/datum/controller/subsystem/job/proc/SetupOccupations() +/datum/controller/subsystem/job/proc/setup_occupations() name_occupations = list() type_occupations = list() @@ -205,20 +204,20 @@ SUBSYSTEM_DEF(job) return TRUE -/datum/controller/subsystem/job/proc/GetJob(rank) +/datum/controller/subsystem/job/proc/get_job(rank) if(!length(all_occupations)) - SetupOccupations() + setup_occupations() return name_occupations[rank] -/datum/controller/subsystem/job/proc/GetJobType(jobtype) +/datum/controller/subsystem/job/proc/get_job_type(jobtype) RETURN_TYPE(/datum/job) if(!length(all_occupations)) - SetupOccupations() + setup_occupations() return type_occupations[jobtype] /datum/controller/subsystem/job/proc/get_department_type(department_type) if(!length(all_occupations)) - SetupOccupations() + setup_occupations() return joinable_departments_by_type[department_type] /** @@ -230,89 +229,92 @@ SUBSYSTEM_DEF(job) * * latejoin - Set to TRUE if this is a latejoin role assignment. * * do_eligibility_checks - Set to TRUE to conduct all job eligibility tests and reject on failure. Set to FALSE if job eligibility has been tested elsewhere and they can be safely skipped. */ -/datum/controller/subsystem/job/proc/AssignRole(mob/dead/new_player/player, datum/job/job, latejoin = FALSE, do_eligibility_checks = TRUE) - JobDebug("Running AR, Player: [player], Job: [isnull(job) ? "null" : job], LateJoin: [latejoin]") +/datum/controller/subsystem/job/proc/assign_role(mob/dead/new_player/player, datum/job/job, latejoin = FALSE, do_eligibility_checks = TRUE) + job_debug("AR: Running, Player: [player], Job: [isnull(job) ? "null" : job], LateJoin: [latejoin]") if(!player?.mind || !job) - JobDebug("AR has failed, player has no mind or job is null, Player: [player], Rank: [isnull(job) ? "null" : job.type]") + job_debug("AR: Failed, player has no mind or job is null. Player: [player], Rank: [isnull(job) ? "null" : job.type]") return FALSE if(do_eligibility_checks && (check_job_eligibility(player, job, "AR", add_job_to_log = TRUE) != JOB_AVAILABLE)) return FALSE - JobDebug("Player: [player] is now Rank: [job.title], JCP:[job.current_positions], JPL:[latejoin ? job.total_positions : job.spawn_positions]") + job_debug("AR: Role now set and assigned - [player] is [job.title], JCP:[job.current_positions], JPL:[latejoin ? job.total_positions : job.spawn_positions]") player.mind.set_assigned_role(job) unassigned -= player job.current_positions++ return TRUE -/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/job/job, level) - JobDebug("Running FOC, Job: [job], Level: [job_priority_level_to_string(level)]") +/datum/controller/subsystem/job/proc/find_occupation_candidates(datum/job/job, level = 0) + job_debug("FOC: Now running, Job: [job], Level: [job_priority_level_to_string(level)]") var/list/candidates = list() for(var/mob/dead/new_player/player in unassigned) if(!player) - JobDebug("FOC player no longer exists.") + job_debug("FOC: Player no longer exists.") continue + if(!player.client) - JobDebug("FOC player client no longer exists, Player: [player]") + job_debug("FOC: Player client no longer exists, Player: [player]") continue + // Initial screening check. Does the player even have the job enabled, if they do - Is it at the correct priority level? var/player_job_level = player.client?.prefs.job_preferences[job.title] if(isnull(player_job_level)) - JobDebug("FOC player job not enabled, Player: [player]") - continue - else if(player_job_level != level) - JobDebug("FOC player job enabled at wrong level, Player: [player], TheirLevel: [job_priority_level_to_string(player_job_level)], ReqLevel: [job_priority_level_to_string(level)]") + job_debug("FOC: Player job not enabled, Player: [player]") continue - // This check handles its own output to JobDebug. + if(level && (player_job_level != level)) + job_debug("FOC: Player job enabled at wrong level, Player: [player], TheirLevel: [job_priority_level_to_string(player_job_level)], ReqLevel: [job_priority_level_to_string(level)]") + continue + + // This check handles its own output to job_debug. if(check_job_eligibility(player, job, "FOC", add_job_to_log = FALSE) != JOB_AVAILABLE) continue // They have the job enabled, at this priority level, with no restrictions applying to them. - JobDebug("FOC pass, Player: [player], Level: [job_priority_level_to_string(level)]") + job_debug("FOC: Player eligible, Player: [player], Level: [job_priority_level_to_string(level)]") candidates += player return candidates -/datum/controller/subsystem/job/proc/GiveRandomJob(mob/dead/new_player/player) - JobDebug("GRJ Giving random job, Player: [player]") +/datum/controller/subsystem/job/proc/give_random_job(mob/dead/new_player/player) + job_debug("GRJ: Giving random job, Player: [player]") . = FALSE for(var/datum/job/job as anything in shuffle(joinable_occupations)) if(QDELETED(player)) - JobDebug("GRJ player is deleted, aborting") + job_debug("GRJ: Player is deleted, aborting") break if((job.current_positions >= job.spawn_positions) && job.spawn_positions != -1) - JobDebug("GRJ job lacks spawn positions to be eligible, Player: [player], Job: [job]") + job_debug("GRJ: Job lacks spawn positions to be eligible, Player: [player], Job: [job]") continue - if(istype(job, GetJobType(overflow_role))) // We don't want to give him assistant, that's boring! - JobDebug("GRJ skipping overflow role, Player: [player], Job: [job]") + if(istype(job, get_job_type(overflow_role))) // We don't want to give him assistant, that's boring! + job_debug("GRJ: Skipping overflow role, Player: [player], Job: [job]") continue if(job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) //If you want a command position, select it! - JobDebug("GRJ skipping command role, Player: [player], Job: [job]") + job_debug("GRJ: Skipping command role, Player: [player], Job: [job]") continue - // This check handles its own output to JobDebug. + // This check handles its own output to job_debug. if(check_job_eligibility(player, job, "GRJ", add_job_to_log = TRUE) != JOB_AVAILABLE) continue - if(AssignRole(player, job, do_eligibility_checks = FALSE)) - JobDebug("GRJ Random job given, Player: [player], Job: [job]") + if(assign_role(player, job, do_eligibility_checks = FALSE)) + job_debug("GRJ: Random job given, Player: [player], Job: [job]") return TRUE - JobDebug("GRJ Player eligible but AssignRole failed, Player: [player], Job: [job]") + job_debug("GRJ: Player eligible but assign_role failed, Player: [player], Job: [job]") -/datum/controller/subsystem/job/proc/ResetOccupations() - JobDebug("Occupations reset.") +/datum/controller/subsystem/job/proc/reset_occupations() + job_debug("RO: Occupations reset.") for(var/mob/dead/new_player/player as anything in GLOB.new_player_list) if(!player?.mind) continue - player.mind.set_assigned_role(GetJobType(/datum/job/unassigned)) + player.mind.set_assigned_role(get_job_type(/datum/job/unassigned)) player.mind.special_role = null - SetupOccupations() + setup_occupations() unassigned = list() if(CONFIG_GET(flag/load_jobs_from_txt)) // Any errors with the configs has already been said, we don't need to repeat them here. @@ -321,12 +323,11 @@ SUBSYSTEM_DEF(job) return -/** - * Will try to select a head, ignoring ALL non-head preferences for every level until. - * - * Basically tries to ensure there is at least one head in every shift if anyone has that job preference enabled at all. +/* + * Forces a random Head of Staff role to be assigned to a random eligible player. + * Returns TRUE if a player was selected and assigned the role. FALSE otherwise. */ -/datum/controller/subsystem/job/proc/FillHeadPosition() +/datum/controller/subsystem/job/proc/force_one_head_assignment() var/datum/job_department/command_department = get_department_type(/datum/job_department/command) if(!command_department) return FALSE @@ -334,60 +335,65 @@ SUBSYSTEM_DEF(job) for(var/datum/job/job as anything in command_department.department_jobs) if((job.current_positions >= job.total_positions) && job.total_positions != -1) continue - var/list/candidates = FindOccupationCandidates(job, level) + var/list/candidates = find_occupation_candidates(job, level) if(!candidates.len) continue var/mob/dead/new_player/candidate = pick(candidates) - // Eligibility checks done as part of FindOccupationCandidates. - if(AssignRole(candidate, job, do_eligibility_checks = FALSE)) + // Eligibility checks done as part of find_occupation_candidates. + if(assign_role(candidate, job, do_eligibility_checks = FALSE)) return TRUE return FALSE /** * Attempts to fill out all possible head positions for players with that job at a a given job priority level. + * Returns the number of Head positions assigned. * * Arguments: - * * level - One of the JP_LOW, JP_MEDIUM or JP_HIGH defines. Attempts to find candidates with head jobs at this priority only. + * * level - One of the JP_LOW, JP_MEDIUM, JP_HIGH or JP_ANY defines. Attempts to find candidates with head jobs at that priority only. */ -/datum/controller/subsystem/job/proc/CheckHeadPositions(level) +/datum/controller/subsystem/job/proc/fill_all_head_positions_at_priority(level) + . = 0 var/datum/job_department/command_department = get_department_type(/datum/job_department/command) + if(!command_department) - return + return . + for(var/datum/job/job as anything in command_department.department_jobs) if((job.current_positions >= job.total_positions) && job.total_positions != -1) continue - var/list/candidates = FindOccupationCandidates(job, level) + var/list/candidates = find_occupation_candidates(job, level) if(!candidates.len) continue var/mob/dead/new_player/candidate = pick(candidates) - // Eligibility checks done as part of FindOccupationCandidates - AssignRole(candidate, job, do_eligibility_checks = FALSE) + // Eligibility checks done as part of find_occupation_candidates + if(assign_role(candidate, job, do_eligibility_checks = FALSE)) + .++ /// Attempts to fill out all available AI positions. /datum/controller/subsystem/job/proc/fill_ai_positions() - var/datum/job/ai_job = GetJob(JOB_AI) + var/datum/job/ai_job = get_job(JOB_AI) if(!ai_job) return // In byond for(in to) loops, the iteration is inclusive so we need to stop at ai_job.total_positions - 1 for(var/i in ai_job.current_positions to ai_job.total_positions - 1) for(var/level in level_order) var/list/candidates = list() - candidates = FindOccupationCandidates(ai_job, level) + candidates = find_occupation_candidates(ai_job, level) if(candidates.len) var/mob/dead/new_player/candidate = pick(candidates) - // Eligibility checks done as part of FindOccupationCandidates - if(AssignRole(candidate, GetJobType(/datum/job/ai), do_eligibility_checks = FALSE)) + // Eligibility checks done as part of find_occupation_candidates + if(assign_role(candidate, get_job_type(/datum/job/ai), do_eligibility_checks = FALSE)) break -/** Proc DivideOccupations +/** Proc divide_occupations * fills var "assigned_role" for all ready players. * This proc must not have any side effect besides of modifying "assigned_role". **/ -/datum/controller/subsystem/job/proc/DivideOccupations(pure = FALSE, allow_all = FALSE) +/datum/controller/subsystem/job/proc/divide_occupations(pure = FALSE, allow_all = FALSE) //Setup new player list and get the jobs list - JobDebug("Running DO, allow_all = [allow_all], pure = [pure]") + job_debug("DO: Running, allow_all = [allow_all], pure = [pure]") run_divide_occupation_pure = pure SEND_SIGNAL(src, COMSIG_OCCUPATIONS_DIVIDED, pure, allow_all) @@ -397,162 +403,166 @@ SUBSYSTEM_DEF(job) if(player.ready == PLAYER_READY_TO_PLAY && player.check_preferences() && player.mind && is_unassigned_job(player.mind.assigned_role)) unassigned += player - initial_players_to_assign = unassigned.len + initial_players_to_assign = length(unassigned) - JobDebug("DO, Len: [unassigned.len]") + job_debug("DO: Player count to assign roles to: [initial_players_to_assign]") //Scale number of open security officer slots to population setup_officer_positions() //Jobs will have fewer access permissions if the number of players exceeds the threshold defined in game_options.txt - var/mat = CONFIG_GET(number/minimal_access_threshold) - if(mat) - if(mat > unassigned.len) + var/min_access_threshold = CONFIG_GET(number/minimal_access_threshold) + if(min_access_threshold) + if(min_access_threshold > initial_players_to_assign) CONFIG_SET(flag/jobs_have_minimal_access, FALSE) else CONFIG_SET(flag/jobs_have_minimal_access, TRUE) - //Shuffle players and jobs - unassigned = shuffle(unassigned) + //Shuffle player list. + shuffle_inplace(unassigned) - HandleFeedbackGathering() + handle_feedback_gathering() - // Dynamic has picked a ruleset that requires enforcing some jobs before others. - JobDebug("DO, Assigning Priority Positions: [length(dynamic_forced_occupations)]") + // Assign any priority positions before all other standard job selections. + job_debug("DO: Assigning priority positions") assign_priority_positions() + job_debug("DO: Priority assignment complete") - //People who wants to be the overflow role, sure, go on. - JobDebug("DO, Running Overflow Check 1") - var/datum/job/overflow_datum = GetJobType(overflow_role) - var/list/overflow_candidates = FindOccupationCandidates(overflow_datum, JP_LOW) - JobDebug("AC1, Candidates: [overflow_candidates.len]") - for(var/mob/dead/new_player/player in overflow_candidates) - JobDebug("AC1 pass, Player: [player]") - // Eligibility checks done as part of FindOccupationCandidates - AssignRole(player, GetJobType(overflow_role), do_eligibility_checks = FALSE) - overflow_candidates -= player - JobDebug("DO, AC1 end") + // The overflow role has limitless slots, plus having the Overflow box ticked in prefs should (with one exception) set the priority to JP_HIGH. + // So everyone with overflow enabled will get that job. Thus we can assign it immediately to all players that have it enabled. + job_debug("DO: Assigning early overflow roles") + assign_all_overflow_positions() + job_debug("DO: Early overflow roles assigned.") - //Select one head - JobDebug("DO, Running Head Check") - FillHeadPosition() - JobDebug("DO, Head Check end") + // At this point we can assume the following: + // From assign_priority_positions() + // 1. If possible, any necessary job roles to allow Dynamic rulesets to execute (such as an AI for malf AI) are satisfied. + // 2. All Head of Staff roles with any player pref set to JP_HIGH are filled out. + // 3. If any player not selected by the above has any Head of Staff preference enabled at any JP_ level, there is at least one Head of Staff. + // + // From assign_all_overflow_positions() + // 4. Anyone with the overflow role enabled has been given the overflow role. - // Fill out any remaining AI positions. - JobDebug("DO, Running AI Check") - fill_ai_positions() - JobDebug("DO, AI Check end") + // Shuffle the joinable occupation list and filter out ineligible occupations due to above job assignments. + var/list/available_occupations = joinable_occupations.Copy() + for(var/datum/job/job in available_occupations) + // Make sure the job isn't filled. If it is, remove it from the list so it doesn't get checked. + if((job.current_positions >= job.spawn_positions) && job.spawn_positions != -1) + job_debug("DO: Job is now filled, Job: [job], Current: [job.current_positions], Limit: [job.spawn_positions]") + available_occupations -= job - //Other jobs are now checked - JobDebug("DO, Running standard job assignment") - // New job giving system by Donkie - // This will cause lots of more loops, but since it's only done once it shouldn't really matter much at all. - // Hopefully this will add more randomness and fairness to job giving. + job_debug("DO: Running standard job assignment") - // Loop through all levels from high to low - var/list/shuffledoccupations = shuffle(joinable_occupations) for(var/level in level_order) - //Check the head jobs first each level - CheckHeadPositions(level) + job_debug("JOBS: Filling in head roles, Level: [job_priority_level_to_string(level)]") + // Fill the head jobs first each level + fill_all_head_positions_at_priority(level) // Loop through all unassigned players for(var/mob/dead/new_player/player in unassigned) if(!allow_all) - if(PopcapReached()) - RejectPlayer(player) + if(popcap_reached()) + job_debug("JOBS: Popcap reached, trying to reject player: [player]") + try_reject_player(player) - // Loop through all jobs - for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY - if(!job) - JobDebug("FOC invalid/null job in occupations, Player: [player], Job: [job]") - shuffledoccupations -= job - continue - - // Make sure the job isn't filled. If it is, remove it from the list so it doesn't get checked again. - if((job.current_positions >= job.spawn_positions) && job.spawn_positions != -1) - JobDebug("FOC job filled and not overflow, Player: [player], Job: [job], Current: [job.current_positions], Limit: [job.spawn_positions]") - shuffledoccupations -= job - continue + job_debug("JOBS: Finding a job for player: [player], at job priority pref: [job_priority_level_to_string(level)]") + // Loop through all jobs and build a list of jobs this player could be eligible for. + var/list/possible_jobs = list() + for(var/datum/job/job in available_occupations) // Filter any job that doesn't fit the current level. var/player_job_level = player.client?.prefs.job_preferences[job.title] if(isnull(player_job_level)) - JobDebug("FOC player job not enabled, Player: [player]") + job_debug("JOBS: Job not enabled, Job: [job]") continue - else if(player_job_level != level) - JobDebug("FOC player job enabled but at different level, Player: [player], TheirLevel: [job_priority_level_to_string(player_job_level)], ReqLevel: [job_priority_level_to_string(level)]") + if(player_job_level != level) + job_debug("JOBS: Job enabled at different priority pref, Job: [job], TheirLevel: [job_priority_level_to_string(player_job_level)], ReqLevel: [job_priority_level_to_string(level)]") continue - if(check_job_eligibility(player, job, "DO", add_job_to_log = TRUE) != JOB_AVAILABLE) + if(check_job_eligibility(player, job, "JOBS", add_job_to_log = TRUE) != JOB_AVAILABLE) continue - JobDebug("DO pass, Player: [player], Level:[level], Job:[job.title]") - AssignRole(player, job, do_eligibility_checks = FALSE) - unassigned -= player - break + possible_jobs += job - JobDebug("DO, Ending standard job assignment") + // If there are no possible jobs for them at this priority, skip them. + if(!length(possible_jobs)) + job_debug("JOBS: Player not eligible for any available jobs at this priority level: [player]") + continue - JobDebug("DO, Handle unassigned.") - // Hand out random jobs to the people who didn't get any in the last check - // Also makes sure that they got their preference correct + // Otherwise, pick one of those jobs at random. + var/datum/job/picked_job = pick(possible_jobs) + + job_debug("JOBS: Now assigning role to player: [player], Job:[picked_job.title]") + assign_role(player, picked_job, do_eligibility_checks = FALSE) + if((picked_job.current_positions >= picked_job.spawn_positions) && picked_job.spawn_positions != -1) + job_debug("JOBS: Job is now full, Job: [picked_job], Positions: [picked_job.current_positions], Limit: [picked_job.spawn_positions]") + available_occupations -= picked_job + + job_debug("DO: Ending standard job assignment") + + job_debug("DO: Handle unassigned") + // For any players that didn't get a job, fall back on their pref setting for what to do. for(var/mob/dead/new_player/player in unassigned) - HandleUnassigned(player, allow_all) - JobDebug("DO, Ending handle unassigned.") + handle_unassigned(player, allow_all) + job_debug("DO: Ending handle unassigned") - JobDebug("DO, Handle unrejectable unassigned") + job_debug("DO: Handle unrejectable unassigned") //Mop up people who can't leave. for(var/mob/dead/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?) - if(!GiveRandomJob(player)) - if(!AssignRole(player, GetJobType(overflow_role))) //If everything is already filled, make them an assistant - JobDebug("DO, Forced antagonist could not be assigned any random job or the overflow role. DivideOccupations failed.") - JobDebug("---------------------------------------------------") + if(!give_random_job(player)) + if(!assign_role(player, get_job_type(overflow_role))) //If everything is already filled, make them an assistant + job_debug("DO: Forced antagonist could not be assigned any random job or the overflow role. divide_occupations failed.") + job_debug("---------------------------------------------------") run_divide_occupation_pure = FALSE return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll - JobDebug("DO, Ending handle unrejectable unassigned") + job_debug("DO: Ending handle unrejectable unassigned") - JobDebug("All divide occupations tasks completed.") - JobDebug("---------------------------------------------------") + job_debug("All divide occupations tasks completed.") + job_debug("---------------------------------------------------") run_divide_occupation_pure = FALSE return TRUE //We couldn't find a job from prefs for this guy. -/datum/controller/subsystem/job/proc/HandleUnassigned(mob/dead/new_player/player, allow_all = FALSE) +/datum/controller/subsystem/job/proc/handle_unassigned(mob/dead/new_player/player, allow_all = FALSE) var/jobless_role = player.client.prefs.read_preference(/datum/preference/choiced/jobless_role) if(!allow_all) - if(PopcapReached()) - RejectPlayer(player) + if(popcap_reached()) + job_debug("HU: Popcap reached, trying to reject player: [player]") + try_reject_player(player) return switch (jobless_role) if (BEOVERFLOW) - var/datum/job/overflow_role_datum = GetJobType(overflow_role) + var/datum/job/overflow_role_datum = get_job_type(overflow_role) if(check_job_eligibility(player, overflow_role_datum, debug_prefix = "HU", add_job_to_log = TRUE) != JOB_AVAILABLE) - RejectPlayer(player) + job_debug("HU: Player cannot be overflow, trying to reject: [player]") + try_reject_player(player) return - if(!AssignRole(player, overflow_role_datum, do_eligibility_checks = FALSE)) - RejectPlayer(player) + if(!assign_role(player, overflow_role_datum, do_eligibility_checks = FALSE)) + job_debug("HU: Player could not be assigned overflow role, trying to reject: [player]") + try_reject_player(player) return if (BERANDOMJOB) - if(!GiveRandomJob(player)) - RejectPlayer(player) + if(!give_random_job(player)) + job_debug("HU: Player cannot be given a random job, trying to reject: [player]") + try_reject_player(player) return if (RETURNTOLOBBY) - RejectPlayer(player) + job_debug("HU: Player unable to be assigned job, return to lobby enabled: [player]") + try_reject_player(player) return else //Something gone wrong if we got here. - var/message = "HU: [player] fell through handling unassigned" - JobDebug(message) - log_game(message) - message_admins(message) - RejectPlayer(player) + job_debug("HU: [player] has an invalid jobless_role var: [jobless_role]") + log_game("[player] has an invalid jobless_role var: [jobless_role]") + message_admins("[player] has an invalid jobless_role, this shouldn't happen.") + try_reject_player(player) //Gives the player the stuff he should have with his rank -/datum/controller/subsystem/job/proc/EquipRank(mob/living/equipping, datum/job/job, client/player_client) +/datum/controller/subsystem/job/proc/equip_rank(mob/living/equipping, datum/job/job, client/player_client) equipping.job = job.title SEND_SIGNAL(equipping, COMSIG_JOB_RECEIVED, job) @@ -572,7 +582,7 @@ SUBSYSTEM_DEF(job) /datum/controller/subsystem/job/proc/handle_auto_deadmin_roles(client/C, rank) if(!C?.holder) return TRUE - var/datum/job/job = GetJob(rank) + var/datum/job/job = get_job(rank) var/timegate_expired = FALSE // allow only forcing deadminning in the first X seconds of the round if auto_deadmin_timegate is set in config @@ -590,7 +600,7 @@ SUBSYSTEM_DEF(job) return C.holder.auto_deadmin() /datum/controller/subsystem/job/proc/setup_officer_positions() - var/datum/job/J = SSjob.GetJob(JOB_SECURITY_OFFICER) + var/datum/job/J = SSjob.get_job(JOB_SECURITY_OFFICER) if(!J) CRASH("setup_officer_positions(): Security officer job is missing") @@ -598,7 +608,7 @@ SUBSYSTEM_DEF(job) if(ssc > 0) if(J.spawn_positions > 0) var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len / ssc))) //Scale between configured minimum and 12 officers - JobDebug("Setting open security officer positions to [officer_positions]") + job_debug("SOP: Setting open security officer positions to [officer_positions]") J.total_positions = officer_positions J.spawn_positions = officer_positions @@ -614,7 +624,7 @@ SUBSYSTEM_DEF(job) else //We ran out of spare locker spawns! break -/datum/controller/subsystem/job/proc/HandleFeedbackGathering() +/datum/controller/subsystem/job/proc/handle_feedback_gathering() for(var/datum/job/job as anything in joinable_occupations) var/high = 0 //high var/medium = 0 //medium @@ -653,7 +663,7 @@ SUBSYSTEM_DEF(job) SSblackbox.record_feedback("nested tally", "job_preferences", young, list("[job.title]", "young")) SSblackbox.record_feedback("nested tally", "job_preferences", newbie, list("[job.title]", "newbie")) -/datum/controller/subsystem/job/proc/PopcapReached() +/datum/controller/subsystem/job/proc/popcap_reached() var/hpc = CONFIG_GET(number/hard_popcap) var/epc = CONFIG_GET(number/extreme_popcap) if(hpc || epc) @@ -662,12 +672,12 @@ SUBSYSTEM_DEF(job) return 1 return 0 -/datum/controller/subsystem/job/proc/RejectPlayer(mob/dead/new_player/player) +/datum/controller/subsystem/job/proc/try_reject_player(mob/dead/new_player/player) if(player.mind && player.mind.special_role) - return - if(PopcapReached()) - JobDebug("Popcap overflow Check observer located, Player: [player]") - JobDebug("Player rejected :[player]") + job_debug("RJCT: Player unable to be rejected due to special_role, Player: [player], SpecialRole: [player.mind.special_role]") + return FALSE + + job_debug("RJCT: Player rejected, Player: [player]") unassigned -= player if(!run_divide_occupation_pure) to_chat(player, "You have failed to qualify for any job you desired.") @@ -679,10 +689,10 @@ SUBSYSTEM_DEF(job) var/oldjobs = SSjob.all_occupations sleep(2 SECONDS) for (var/datum/job/job as anything in oldjobs) - INVOKE_ASYNC(src, PROC_REF(RecoverJob), job) + INVOKE_ASYNC(src, PROC_REF(recover_job), job) -/datum/controller/subsystem/job/proc/RecoverJob(datum/job/J) - var/datum/job/newjob = GetJob(J.title) +/datum/controller/subsystem/job/proc/recover_job(datum/job/J) + var/datum/job/newjob = get_job(J.title) if (!istype(newjob)) return newjob.total_positions = J.total_positions @@ -699,7 +709,7 @@ SUBSYSTEM_DEF(job) if(buckle && isliving(joining_mob)) buckle_mob(joining_mob, FALSE, FALSE) -/datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE) +/datum/controller/subsystem/job/proc/send_to_late_join(mob/M, buckle = TRUE) var/atom/destination if(M.mind && !is_unassigned_job(M.mind.assigned_role) && length(GLOB.jobspawn_overrides[M.mind.assigned_role.title])) //We're doing something special today. destination = pick(GLOB.jobspawn_overrides[M.mind.assigned_role.title]) @@ -734,19 +744,6 @@ SUBSYSTEM_DEF(job) stack_trace("Unable to find last resort spawn point.") return GET_ERROR_ROOM -///Lands specified mob at a random spot in the hallways -/datum/controller/subsystem/job/proc/DropLandAtRandomHallwayPoint(mob/living/living_mob) - var/turf/spawn_turf = get_safe_random_station_turf(typesof(/area/station/hallway)) - - if(!spawn_turf) - SendToLateJoin(living_mob) - else - podspawn(list( - "target" = spawn_turf, - "path" = /obj/structure/closet/supplypod/centcompod, - "spawn" = living_mob - )) - /// Returns a list of minds of all heads of staff who are alive /datum/controller/subsystem/job/proc/get_living_heads() . = list() @@ -781,7 +778,7 @@ SUBSYSTEM_DEF(job) if(sec.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_SECURITY) . += sec -/datum/controller/subsystem/job/proc/JobDebug(message) +/datum/controller/subsystem/job/proc/job_debug(message) log_job_debug(message) /// Builds various lists of jobs based on station, centcom and additional jobs with icons associated with them. @@ -846,12 +843,47 @@ SUBSYSTEM_DEF(job) safe_code_timer_id = null safe_code_request_loc = null -/// Blindly assigns the required roles to every player in the dynamic_forced_occupations list. +/// Assigns roles that are considered high priority, either due to dynamic needing to force a specific role for a specific ruleset +/// or making sure roles critical to round progression exist where possible every shift. /datum/controller/subsystem/job/proc/assign_priority_positions() + job_debug("APP: Assigning Dynamic ruleset forced occupations: [length(dynamic_forced_occupations)]") for(var/mob/new_player in dynamic_forced_occupations) - // Eligibility checks already carried out as part of the dynamic ruleset trim_candidates proc.area - // However no guarantee of game state between then and now, so don't skip eligibility checks on AssignRole. - AssignRole(new_player, GetJob(dynamic_forced_occupations[new_player])) + // Eligibility checks already carried out as part of the dynamic ruleset trim_candidates proc. + // However no guarantee of game state between then and now, so don't skip eligibility checks on assign_role. + assign_role(new_player, get_job(dynamic_forced_occupations[new_player])) + + // Get JP_HIGH department Heads of Staff in place. Indirectly useful for the Revolution ruleset to have as many Heads as possible. + job_debug("APP: Assigning all JP_HIGH head of staff roles.") + var/head_count = fill_all_head_positions_at_priority(JP_HIGH) + + // If nobody has JP_HIGH on a Head role, try to force at least one Head of Staff so every shift has the best chance + // of having at least one leadership role. + if(head_count == 0) + force_one_head_assignment() + + // Fill out all AI positions. + job_debug("APP: Filling all AI positions") + fill_ai_positions() + +/datum/controller/subsystem/job/proc/assign_all_overflow_positions() + job_debug("OVRFLW: Assigning all overflow roles.") + job_debug("OVRFLW: This shift's overflow role: [overflow_role]") + var/datum/job/overflow_datum = get_job_type(overflow_role) + + // When the Overflow role changes for any reason, this allows players to set otherwise invalid job priority pref states. + // So if Assistant is the "usual" Overflow but it gets changed to Clown for a shift, players can set the Assistant role's priorities + // to JP_MEDIUM and JP_LOW. When the "usual" Overflow role comes back, it returns to an On option in the prefs menu but still + // keeps its old JP_MEDIUM or JP_LOW value in the background. + + // Due to this prefs quirk, we actually don't want to find JP_HIGH candidates as it may exclude people with abnormal pref states that + // appear normal from the UI. By passing in JP_ANY, it will return all players that have the overflow job pref (which should be a toggle) + // set to any level. + var/list/overflow_candidates = find_occupation_candidates(overflow_datum, JP_ANY) + for(var/mob/dead/new_player/player in overflow_candidates) + // Eligibility checks done as part of find_occupation_candidates, so skip them. + assign_role(player, get_job_type(overflow_role), do_eligibility_checks = FALSE) + job_debug("OVRFLW: Assigned overflow to player: [player]") + job_debug("OVRFLW: All overflow roles assigned.") /// Takes a job priority #define such as JP_LOW and gets its string representation for logging. /datum/controller/subsystem/job/proc/job_priority_level_to_string(priority) @@ -869,40 +901,40 @@ SUBSYSTEM_DEF(job) * Arguments: * * player - The player to check for job eligibility. * * possible_job - The job to check for eligibility against. - * * debug_prefix - Logging prefix for the JobDebug log entries. For example, GRJ during GiveRandomJob or DO during DivideOccupations. + * * debug_prefix - Logging prefix for the job_debug log entries. For example, GRJ during give_random_job or DO during divide_occupations. * * add_job_to_log - If TRUE, appends the job type to the log entry. If FALSE, does not. Set to FALSE when check is part of iterating over players for a specific job, set to TRUE when check is part of iterating over jobs for a specific player and you don't want extra log entry spam. */ /datum/controller/subsystem/job/proc/check_job_eligibility(mob/dead/new_player/player, datum/job/possible_job, debug_prefix = "", add_job_to_log = FALSE) if(!player.mind) - JobDebug("[debug_prefix] player has no mind, Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") + job_debug("[debug_prefix]: Player has no mind, Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") return JOB_UNAVAILABLE_GENERIC if(possible_job.title in player.mind.restricted_roles) - JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_ANTAG_INCOMPAT, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") + job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_ANTAG_INCOMPAT, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") return JOB_UNAVAILABLE_ANTAG_INCOMPAT if(!possible_job.player_old_enough(player.client)) - JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_ACCOUNTAGE, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") + job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_ACCOUNTAGE, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") return JOB_UNAVAILABLE_ACCOUNTAGE var/required_playtime_remaining = possible_job.required_playtime_remaining(player.client) if(required_playtime_remaining) - JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_PLAYTIME, possible_job.title)], Player: [player], MissingTime: [required_playtime_remaining][add_job_to_log ? ", Job: [possible_job]" : ""]") + job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_PLAYTIME, possible_job.title)], Player: [player], MissingTime: [required_playtime_remaining][add_job_to_log ? ", Job: [possible_job]" : ""]") return JOB_UNAVAILABLE_PLAYTIME // Run the banned check last since it should be the rarest check to fail and can access the database. if(is_banned_from(player.ckey, possible_job.title)) - JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_BANNED, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") + job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_BANNED, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") return JOB_UNAVAILABLE_BANNED // Check for character age if(possible_job.required_character_age > player.client.prefs.read_preference(/datum/preference/numeric/age) && possible_job.required_character_age != null) - JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_AGE)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") + job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_AGE)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") return JOB_UNAVAILABLE_AGE // Need to recheck the player exists after is_banned_from since it can query the DB which may sleep. if(QDELETED(player)) - JobDebug("[debug_prefix] player is qdeleted, Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") + job_debug("[debug_prefix]: Player is qdeleted, Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") return JOB_UNAVAILABLE_GENERIC return JOB_AVAILABLE diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index ff76464bee5..976f00a6a6a 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -236,14 +236,14 @@ SUBSYSTEM_DEF(ticker) can_continue = SSdynamic.pre_setup() //Choose antagonists CHECK_TICK SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PRE_JOBS_ASSIGNED, src) - can_continue = can_continue && SSjob.DivideOccupations() //Distribute jobs + can_continue = can_continue && SSjob.divide_occupations() //Distribute jobs CHECK_TICK if(!GLOB.Debug2) if(!can_continue) log_game("Game failed pre_setup") to_chat(world, "Error setting up game. Reverting to pre-game lobby.") - SSjob.ResetOccupations() + SSjob.reset_occupations() return FALSE else message_admins(span_notice("DEBUG: Bypassing prestart checks...")) @@ -416,7 +416,7 @@ SUBSYSTEM_DEF(ticker) continue var/datum/job/player_assigned_role = new_player_living.mind.assigned_role if(player_assigned_role.job_flags & JOB_EQUIP_RANK) - SSjob.EquipRank(new_player_living, player_assigned_role, new_player_mob.client) + SSjob.equip_rank(new_player_living, player_assigned_role, new_player_mob.client) player_assigned_role.after_roundstart_spawn(new_player_living, new_player_mob.client) if(picked_spare_id_candidate == new_player_mob) captainless = FALSE diff --git a/code/datums/ai_laws/ai_laws.dm b/code/datums/ai_laws/ai_laws.dm index 0dbc6839430..a0d1d629fc8 100644 --- a/code/datums/ai_laws/ai_laws.dm +++ b/code/datums/ai_laws/ai_laws.dm @@ -192,7 +192,7 @@ GLOBAL_VAR(round_default_lawset) var/datum/ai_laws/default_laws = get_round_default_lawset() default_laws = new default_laws() inherent = default_laws.inherent - var/datum/job/human_ai_job = SSjob.GetJob(JOB_HUMAN_AI) + var/datum/job/human_ai_job = SSjob.get_job(JOB_HUMAN_AI) if(human_ai_job && human_ai_job.current_positions && !zeroth) //there is a human AI so we "slave" to that. zeroth = "Follow the orders of Big Brother." protected_zeroth = TRUE diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index f4c78bc9007..99467c57099 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -156,11 +156,11 @@ for(var/job in appearance_from_prefs.job_preferences) var/this_pref = appearance_from_prefs.job_preferences[job] if(this_pref > highest_pref) - appearance_job = SSjob.GetJob(job) + appearance_job = SSjob.get_job(job) highest_pref = this_pref if(!appearance_job) - appearance_job = SSjob.GetJob(JOB_ASSISTANT) + appearance_job = SSjob.get_job(JOB_ASSISTANT) if(istype(appearance_job, /datum/job/ai)) human_image = icon('icons/mob/silicon/ai.dmi', icon_state = resolve_ai_icon(appearance_from_prefs.read_preference(/datum/preference/choiced/ai_core_display)), dir = SOUTH) diff --git a/code/datums/elements/art.dm b/code/datums/elements/art.dm index 81d388aa94a..d5a642c23d0 100644 --- a/code/datums/elements/art.dm +++ b/code/datums/elements/art.dm @@ -74,7 +74,7 @@ var/datum/job_department/hater_department = SSjob.get_department_type(hater_department_type) for(var/datum/job/hater_job as anything in hater_department.department_jobs) haters += hater_job.title - var/datum/job/quartermaster/fucking_quartermaster = SSjob.GetJobType(/datum/job/quartermaster) + var/datum/job/quartermaster/fucking_quartermaster = SSjob.get_job_type(/datum/job/quartermaster) haters += fucking_quartermaster.title if(!(user.mind.assigned_role.title in haters)) diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm index 133fbce92bb..c7514b86a1b 100644 --- a/code/datums/id_trim/jobs.dm +++ b/code/datums/id_trim/jobs.dm @@ -24,7 +24,7 @@ /datum/id_trim/job/New() if(ispath(job)) - job = SSjob.GetJobType(job) + job = SSjob.get_job_type(job) if(isnull(job_changes)) job_changes = SSmapping.config.job_changes @@ -1093,7 +1093,7 @@ if(CONFIG_GET(number/depsec_access_level) == POPULATION_SCALED_ACCESS) var/minimal_security_officers = 3 // We do not spawn in any more lockers if there are 5 or less security officers, so let's keep it lower than that number. - var/datum/job/J = SSjob.GetJob(JOB_SECURITY_OFFICER) + var/datum/job/J = SSjob.get_job(JOB_SECURITY_OFFICER) if((J.spawn_positions - minimal_security_officers) <= 0) access |= elevated_access diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm index 36e9d7ba6d0..397a1c5b13a 100644 --- a/code/datums/mind/_mind.dm +++ b/code/datums/mind/_mind.dm @@ -106,7 +106,7 @@ /datum/mind/New(_key) key = _key init_known_skills() - set_assigned_role(SSjob.GetJobType(/datum/job/unassigned)) // Unassigned by default. + set_assigned_role(SSjob.get_job_type(/datum/job/unassigned)) // Unassigned by default. /datum/mind/Destroy() SSticker.minds -= src @@ -251,7 +251,7 @@ var/new_role = input("Select new role", "Assigned role", assigned_role.title) as null|anything in sort_list(SSjob.name_occupations) if(isnull(new_role)) return - var/datum/job/new_job = SSjob.GetJob(new_role) + var/datum/job/new_job = SSjob.get_job(new_role) if (!new_job) to_chat(usr, span_warning("Job not found.")) return diff --git a/code/datums/mind/antag.dm b/code/datums/mind/antag.dm index 11340ae56a6..ca10f3afe20 100644 --- a/code/datums/mind/antag.dm +++ b/code/datums/mind/antag.dm @@ -286,7 +286,7 @@ /datum/mind/proc/make_wizard() if(has_antag_datum(/datum/antagonist/wizard)) return - set_assigned_role(SSjob.GetJobType(/datum/job/space_wizard)) + set_assigned_role(SSjob.get_job_type(/datum/job/space_wizard)) special_role = ROLE_WIZARD add_antag_datum(/datum/antagonist/wizard) diff --git a/code/datums/mind/initialization.dm b/code/datums/mind/initialization.dm index eb622cc5af5..e3b3e8225dc 100644 --- a/code/datums/mind/initialization.dm +++ b/code/datums/mind/initialization.dm @@ -21,17 +21,17 @@ //AI /mob/living/silicon/ai/mind_initialize() . = ..() - mind.set_assigned_role(SSjob.GetJobType(/datum/job/ai)) + mind.set_assigned_role(SSjob.get_job_type(/datum/job/ai)) //BORG /mob/living/silicon/robot/mind_initialize() . = ..() - mind.set_assigned_role(SSjob.GetJobType(/datum/job/cyborg)) + mind.set_assigned_role(SSjob.get_job_type(/datum/job/cyborg)) //PAI /mob/living/silicon/pai/mind_initialize() . = ..() - mind.set_assigned_role(SSjob.GetJobType(/datum/job/personal_ai)) + mind.set_assigned_role(SSjob.get_job_type(/datum/job/personal_ai)) mind.special_role = "" diff --git a/code/datums/records/manifest.dm b/code/datums/records/manifest.dm index fc2bb30ce8d..afc5cef6aa4 100644 --- a/code/datums/records/manifest.dm +++ b/code/datums/records/manifest.dm @@ -31,7 +31,7 @@ GLOBAL_DATUM_INIT(manifest, /datum/manifest, new) var/name = target.name var/rank = target.rank // user-visible job var/trim = target.trim // internal jobs by trim type - var/datum/job/job = SSjob.GetJob(trim) + var/datum/job/job = SSjob.get_job(trim) if(!job || !(job.job_flags & JOB_CREW_MANIFEST) || !LAZYLEN(job.departments_list)) // In case an unlawful custom rank is added. var/list/misc_list = manifest_out[DEPARTMENT_UNASSIGNED] misc_list[++misc_list.len] = list( diff --git a/code/datums/station_traits/job_traits.dm b/code/datums/station_traits/job_traits.dm index 2564955c179..4d41ee37861 100644 --- a/code/datums/station_traits/job_traits.dm +++ b/code/datums/station_traits/job_traits.dm @@ -61,7 +61,7 @@ if (isnull(signee) || !signee.client || !signee.mind || signee.ready != PLAYER_READY_TO_PLAY) LAZYREMOVE(lobby_candidates, signee) - var/datum/job/our_job = SSjob.GetJobType(job_to_add) + var/datum/job/our_job = SSjob.get_job_type(job_to_add) our_job.total_positions = position_amount our_job.spawn_positions = position_amount while(length(lobby_candidates) && position_amount > 0) @@ -73,7 +73,7 @@ lobby_candidates = null /datum/station_trait/job/can_display_lobby_button(client/player) - var/datum/job/our_job = SSjob.GetJobType(job_to_add) + var/datum/job/our_job = SSjob.get_job_type(job_to_add) return our_job.player_old_enough(player) && ..() /// Adds a gorilla to the cargo department, replacing the sloth and the mech diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index df4e4555d7e..31fc68b3142 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -573,7 +573,7 @@ DEFINE_BITFIELD(turret_flags, list( // If we aren't shooting heads then return a threatcount of 0 if (!(turret_flags & TURRET_FLAG_SHOOT_HEADS)) - var/datum/job/apparent_job = SSjob.GetJob(perp.get_assignment()) + var/datum/job/apparent_job = SSjob.get_job(perp.get_assignment()) if(apparent_job?.job_flags & JOB_HEAD_OF_STAFF) return 0 diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 1f20ea9bc3e..65daf8141c4 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -125,7 +125,7 @@ /obj/item/card/id/Initialize(mapload) . = ..() - var/datum/bank_account/blank_bank_account = new("Unassigned", SSjob.GetJobType(/datum/job/unassigned), player_account = FALSE) + var/datum/bank_account/blank_bank_account = new("Unassigned", SSjob.get_job_type(/datum/job/unassigned), player_account = FALSE) registered_account = blank_bank_account registered_account.replaceable = TRUE @@ -1289,7 +1289,7 @@ . = ..() registered_account = new(player_account = FALSE) registered_account.account_id = ADMIN_ACCOUNT_ID // this is so bank_card_talk() can work. - registered_account.account_job = SSjob.GetJobType(/datum/job/admin) + registered_account.account_job = SSjob.get_job_type(/datum/job/admin) registered_account.account_balance += 999999 // MONEY! We add more money to the account every time we spawn because it's a debug item and infinite money whoopie /obj/item/card/id/advanced/debug/alt_click_can_use_id(mob/living/user) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 68096367ef8..adb737612df 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -523,7 +523,7 @@ ADMIN_VERB(spawn_debug_full_crew, R_DEBUG, "Spawn Debug Full Crew", "Creates a f // Then, spawn a human and slap a person into it. var/number_made = 0 for(var/rank in SSjob.name_occupations) - var/datum/job/job = SSjob.GetJob(rank) + var/datum/job/job = SSjob.get_job(rank) // JOB_CREW_MEMBER is all jobs that pretty much aren't silicon if(!(job.job_flags & JOB_CREW_MEMBER)) @@ -535,7 +535,7 @@ ADMIN_VERB(spawn_debug_full_crew, R_DEBUG, "Spawn Debug Full Crew", "Creates a f new_guy.mind.name = "[rank] Dummy" // Assign the rank to the new player dummy. - if(!SSjob.AssignRole(new_guy, job, do_eligibility_checks = FALSE)) + if(!SSjob.assign_role(new_guy, job, do_eligibility_checks = FALSE)) qdel(new_guy) to_chat(user, "[rank] wasn't able to be spawned.") continue @@ -547,7 +547,7 @@ ADMIN_VERB(spawn_debug_full_crew, R_DEBUG, "Spawn Debug Full Crew", "Creates a f qdel(new_guy) // Then equip up the human with job gear. - SSjob.EquipRank(character, job) + SSjob.equip_rank(character, job) job.after_latejoin_spawn(character) // Finally, ensure the minds are tracked and in the manifest. diff --git a/code/modules/admin/verbs/admin.dm b/code/modules/admin/verbs/admin.dm index 88ee5148f7a..edd362938af 100644 --- a/code/modules/admin/verbs/admin.dm +++ b/code/modules/admin/verbs/admin.dm @@ -32,7 +32,7 @@ ADMIN_VERB(unprison, R_ADMIN, "UnPrison", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEG tgui_alert(user, "[prisoner.name] is not prisoned.") return - SSjob.SendToLateJoin(prisoner) + SSjob.send_to_late_join(prisoner) message_admins("[key_name_admin(user)] has unprisoned [key_name_admin(prisoner)]") log_admin("[key_name(user)] has unprisoned [key_name(prisoner)]") BLACKBOX_LOG_ADMIN_VERB("Unprison") diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index 57311446961..aef16dc7d7d 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -190,7 +190,7 @@ ADMIN_VERB(respawn_character, R_ADMIN, "Respawn Character", "Respawn a player th if(findtext(G_found.real_name,"monkey")) if(tgui_alert(user,"This character appears to have been a monkey. Would you like to respawn them as such?",,list("Yes","No")) == "Yes") var/mob/living/carbon/human/species/monkey/new_monkey = new - SSjob.SendToLateJoin(new_monkey) + SSjob.send_to_late_join(new_monkey) G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use new_monkey.key = G_found.key to_chat(new_monkey, "You have been fully respawned. Enjoy the game.", confidential = TRUE) @@ -202,7 +202,7 @@ ADMIN_VERB(respawn_character, R_ADMIN, "Respawn Character", "Respawn a player th //Ok, it's not a monkey. So, spawn a human. var/mob/living/carbon/human/new_character = new//The mob being spawned. - SSjob.SendToLateJoin(new_character) + SSjob.send_to_late_join(new_character) var/datum/record/locked/record_found //Referenced to later to either randomize or not randomize the character. if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something @@ -225,7 +225,7 @@ ADMIN_VERB(respawn_character, R_ADMIN, "Respawn Character", "Respawn a player th else new_character.mind_initialize() if(is_unassigned_job(new_character.mind.assigned_role)) - new_character.mind.set_assigned_role(SSjob.GetJobType(SSjob.overflow_role)) + new_character.mind.set_assigned_role(SSjob.get_job_type(SSjob.overflow_role)) new_character.key = G_found.key @@ -242,7 +242,7 @@ ADMIN_VERB(respawn_character, R_ADMIN, "Respawn Character", "Respawn a player th //Now for special roles and equipment. var/datum/antagonist/traitor/traitordatum = new_character.mind.has_antag_datum(/datum/antagonist/traitor) if(traitordatum) - SSjob.EquipRank(new_character, new_character.mind.assigned_role, new_character.client) + SSjob.equip_rank(new_character, new_character.mind.assigned_role, new_character.client) new_character.mind.give_uplink(silent = TRUE, antag_datum = traitordatum) switch(new_character.mind.special_role) @@ -271,7 +271,7 @@ ADMIN_VERB(respawn_character, R_ADMIN, "Respawn Character", "Respawn a player th new_character = new_character.AIize() else if(!traitordatum) // Already equipped there. - SSjob.EquipRank(new_character, new_character.mind.assigned_role, new_character.client)//Or we simply equip them. + SSjob.equip_rank(new_character, new_character.mind.assigned_role, new_character.client)//Or we simply equip them. //Announces the character on all the systems, based on the record. if(!record_found && (new_character.mind.assigned_role.job_flags & JOB_CREW_MEMBER)) diff --git a/code/modules/admin/verbs/ai_triumvirate.dm b/code/modules/admin/verbs/ai_triumvirate.dm index d63994a25c3..38c2eba712c 100644 --- a/code/modules/admin/verbs/ai_triumvirate.dm +++ b/code/modules/admin/verbs/ai_triumvirate.dm @@ -36,7 +36,7 @@ GLOBAL_DATUM(triple_ai_controller, /datum/triple_ai_controller) to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.", confidential = TRUE) return - var/datum/job/job = SSjob.GetJobType(/datum/job/ai) + var/datum/job/job = SSjob.get_job_type(/datum/job/ai) if(!job) to_chat(usr, "Unable to locate the AI job", confidential = TRUE) CRASH("triple_ai() called, no /datum/job/ai to be found.") diff --git a/code/modules/admin/verbs/ert.dm b/code/modules/admin/verbs/ert.dm index 441a5d0dd56..23f1627503e 100644 --- a/code/modules/admin/verbs/ert.dm +++ b/code/modules/admin/verbs/ert.dm @@ -248,7 +248,7 @@ ert_antag.random_names = ertemplate.random_names ert_operative.mind.add_antag_datum(ert_antag,ert_team) - ert_operative.mind.set_assigned_role(SSjob.GetJobType(ert_antag.ert_job_path)) + ert_operative.mind.set_assigned_role(SSjob.get_job_type(ert_antag.ert_job_path)) //Logging and cleanup ert_operative.log_message("has been selected as \a [ert_antag.name].", LOG_GAME) diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index bcb89379ef4..9012a8652bb 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -84,7 +84,7 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w if("infinite_sec") if(!is_debugger) return - var/datum/job/sec_job = SSjob.GetJobType(/datum/job/security_officer) + var/datum/job/sec_job = SSjob.get_job_type(/datum/job/security_officer) sec_job.total_positions = -1 sec_job.spawn_positions = -1 message_admins("[key_name_admin(holder)] has removed the cap on security officers.") diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index 2e418c78d6c..da7c7e9e39c 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -83,7 +83,7 @@ app.wiz_team = master_wizard.wiz_team master_wizard.wiz_team.add_member(app_mind) app_mind.add_antag_datum(app) - app_mind.set_assigned_role(SSjob.GetJobType(/datum/job/wizard_apprentice)) + app_mind.set_assigned_role(SSjob.get_job_type(/datum/job/wizard_apprentice)) app_mind.special_role = ROLE_WIZARD_APPRENTICE SEND_SOUND(M, sound('sound/effects/magic.ogg')) diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index 7fc0c565ab1..cd56fcdaa5c 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -70,7 +70,7 @@ return team /datum/antagonist/abductor/on_gain() - owner.set_assigned_role(SSjob.GetJobType(role_job)) + owner.set_assigned_role(SSjob.get_job_type(role_job)) owner.special_role = ROLE_ABDUCTOR objectives += team.objectives finalize_abductor() diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm index 09790f4ba89..27093778c31 100644 --- a/code/modules/antagonists/abductor/machinery/experiment.dm +++ b/code/modules/antagonists/abductor/machinery/experiment.dm @@ -190,7 +190,7 @@ H.forceMove(console.pad.teleport_target) return //Area not chosen / It's not safe area - teleport to arrivals - SSjob.SendToLateJoin(H, FALSE) + SSjob.send_to_late_join(H, FALSE) return /obj/machinery/abductor/experiment/update_icon_state() diff --git a/code/modules/antagonists/clown_ops/clownop.dm b/code/modules/antagonists/clown_ops/clownop.dm index 07c1cc84ad7..9866ee30ccf 100644 --- a/code/modules/antagonists/clown_ops/clownop.dm +++ b/code/modules/antagonists/clown_ops/clownop.dm @@ -11,7 +11,7 @@ nuke_icon_state = "bananiumbomb_base" /datum/antagonist/nukeop/clownop/admin_add(datum/mind/new_owner,mob/admin) - new_owner.set_assigned_role(SSjob.GetJobType(/datum/job/clown_operative)) + new_owner.set_assigned_role(SSjob.get_job_type(/datum/job/clown_operative)) new_owner.add_antag_datum(src) message_admins("[key_name_admin(admin)] has clown op'ed [key_name_admin(new_owner)].") log_admin("[key_name(admin)] has clown op'ed [key_name(new_owner)].") diff --git a/code/modules/antagonists/nukeop/datums/operative.dm b/code/modules/antagonists/nukeop/datums/operative.dm index 9eca88d3385..c05295e15d3 100644 --- a/code/modules/antagonists/nukeop/datums/operative.dm +++ b/code/modules/antagonists/nukeop/datums/operative.dm @@ -94,7 +94,7 @@ nuke_team = new_team /datum/antagonist/nukeop/admin_add(datum/mind/new_owner,mob/admin) - new_owner.set_assigned_role(SSjob.GetJobType(/datum/job/nuclear_operative)) + new_owner.set_assigned_role(SSjob.get_job_type(/datum/job/nuclear_operative)) new_owner.add_antag_datum(src) message_admins("[key_name_admin(admin)] has nuke op'ed [key_name_admin(new_owner)].") log_admin("[key_name(admin)] has nuke op'ed [key_name(new_owner)].") diff --git a/code/modules/antagonists/paradox_clone/paradox_clone.dm b/code/modules/antagonists/paradox_clone/paradox_clone.dm index e809e8cecbf..bd8eb7cd7d8 100644 --- a/code/modules/antagonists/paradox_clone/paradox_clone.dm +++ b/code/modules/antagonists/paradox_clone/paradox_clone.dm @@ -52,7 +52,7 @@ kill.update_explanation_text() objectives += kill - owner.set_assigned_role(SSjob.GetJobType(/datum/job/paradox_clone)) + owner.set_assigned_role(SSjob.get_job_type(/datum/job/paradox_clone)) //clone doesnt show up on message lists var/obj/item/modular_computer/pda/messenger = locate() in owner.current diff --git a/code/modules/antagonists/space_dragon/space_dragon.dm b/code/modules/antagonists/space_dragon/space_dragon.dm index 0d982dc492d..cc82f491c1f 100644 --- a/code/modules/antagonists/space_dragon/space_dragon.dm +++ b/code/modules/antagonists/space_dragon/space_dragon.dm @@ -67,12 +67,12 @@ forge_objectives() rift_ability = new() owner.special_role = ROLE_SPACE_DRAGON - owner.set_assigned_role(SSjob.GetJobType(/datum/job/space_dragon)) + owner.set_assigned_role(SSjob.get_job_type(/datum/job/space_dragon)) return ..() /datum/antagonist/space_dragon/on_removal() owner.special_role = null - owner.set_assigned_role(SSjob.GetJobType(/datum/job/unassigned)) + owner.set_assigned_role(SSjob.get_job_type(/datum/job/unassigned)) return ..() /datum/antagonist/space_dragon/apply_innate_effects(mob/living/mob_override) diff --git a/code/modules/antagonists/space_ninja/space_ninja.dm b/code/modules/antagonists/space_ninja/space_ninja.dm index 7f88c687c12..37bc2299928 100644 --- a/code/modules/antagonists/space_ninja/space_ninja.dm +++ b/code/modules/antagonists/space_ninja/space_ninja.dm @@ -114,12 +114,12 @@ equip_space_ninja(owner.current) owner.current.add_quirk(/datum/quirk/freerunning) owner.current.add_quirk(/datum/quirk/light_step) - owner.current.mind.set_assigned_role(SSjob.GetJobType(/datum/job/space_ninja)) + owner.current.mind.set_assigned_role(SSjob.get_job_type(/datum/job/space_ninja)) owner.current.mind.special_role = ROLE_NINJA return ..() /datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin) - new_owner.set_assigned_role(SSjob.GetJobType(/datum/job/space_ninja)) + new_owner.set_assigned_role(SSjob.get_job_type(/datum/job/space_ninja)) new_owner.special_role = ROLE_NINJA new_owner.add_antag_datum(src) message_admins("[key_name_admin(admin)] has ninja'ed [key_name_admin(new_owner)].") diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index 335c934a320..fa6d9a515b6 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -124,7 +124,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key) if(!owner.current) return if(!GLOB.wizardstart.len) - SSjob.SendToLateJoin(owner.current) + SSjob.send_to_late_join(owner.current) to_chat(owner, "HOT INSERTION, GO GO GO") owner.current.forceMove(pick(GLOB.wizardstart)) diff --git a/code/modules/antagonists/xeno/xeno.dm b/code/modules/antagonists/xeno/xeno.dm index 59c83fd52ed..5ef26665bf2 100644 --- a/code/modules/antagonists/xeno/xeno.dm +++ b/code/modules/antagonists/xeno/xeno.dm @@ -160,7 +160,7 @@ else mind.add_antag_datum(/datum/antagonist/xeno) - mind.set_assigned_role(SSjob.GetJobType(/datum/job/xenomorph)) + mind.set_assigned_role(SSjob.get_job_type(/datum/job/xenomorph)) mind.special_role = ROLE_ALIEN /mob/living/carbon/alien/on_wabbajacked(mob/living/new_mob) @@ -170,7 +170,7 @@ if(isalien(new_mob)) return mind.remove_antag_datum(/datum/antagonist/xeno) - mind.set_assigned_role(SSjob.GetJobType(/datum/job/unassigned)) + mind.set_assigned_role(SSjob.get_job_type(/datum/job/unassigned)) mind.special_role = null #undef CAPTIVE_XENO_DEAD diff --git a/code/modules/bitrunning/server/threats.dm b/code/modules/bitrunning/server/threats.dm index 6b9a334d925..ea612a43efa 100644 --- a/code/modules/bitrunning/server/threats.dm +++ b/code/modules/bitrunning/server/threats.dm @@ -119,7 +119,7 @@ var/datum/mind/antag_mind = new_mob.mind antag_mind.add_antag_datum(chosen_role) antag_mind.special_role = ROLE_GLITCH - antag_mind.set_assigned_role(SSjob.GetJobType(/datum/job/bitrunning_glitch)) + antag_mind.set_assigned_role(SSjob.get_job_type(/datum/job/bitrunning_glitch)) playsound(new_mob, 'sound/magic/ethereal_exit.ogg', 50, vary = TRUE) message_admins("[ADMIN_LOOKUPFLW(new_mob)] has been made into virtual antagonist by an event.") diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index c078a23e89c..eafda7f792e 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -181,7 +181,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) data["character_profiles"] = create_character_profiles() data["character_preview_view"] = character_preview_view.assigned_map - data["overflow_role"] = SSjob.GetJobType(SSjob.overflow_role).title + data["overflow_role"] = SSjob.get_job_type(SSjob.overflow_role).title data["window"] = current_window data["content_unlocked"] = unlock_content diff --git a/code/modules/client/preferences/middleware/jobs.dm b/code/modules/client/preferences/middleware/jobs.dm index 201e57668ea..392822eac61 100644 --- a/code/modules/client/preferences/middleware/jobs.dm +++ b/code/modules/client/preferences/middleware/jobs.dm @@ -10,7 +10,7 @@ if (level != null && level != JP_LOW && level != JP_MEDIUM && level != JP_HIGH) return FALSE - var/datum/job/job = SSjob.GetJob(job_title) + var/datum/job/job = SSjob.get_job(job_title) if (isnull(job)) return FALSE diff --git a/code/modules/client/preferences/species_features/vampire.dm b/code/modules/client/preferences/species_features/vampire.dm index 5ecdae7b1bf..f720dca3649 100644 --- a/code/modules/client/preferences/species_features/vampire.dm +++ b/code/modules/client/preferences/species_features/vampire.dm @@ -32,7 +32,7 @@ GLOBAL_LIST_EMPTY(vampire_houses) //find and setup the house (department) this vampire is joining var/datum/job_department/vampire_house - var/datum/job/vampire_job = SSjob.GetJob(target.job) + var/datum/job/vampire_job = SSjob.get_job(target.job) if(!vampire_job) //no job or no mind LOSERS return var/list/valid_departments = (SSjob.joinable_departments.Copy()) - list(/datum/job_department/silicon, /datum/job_department/undefined) diff --git a/code/modules/clothing/chameleon/_chameleon_action.dm b/code/modules/clothing/chameleon/_chameleon_action.dm index 7d11355791b..b9a1697976b 100644 --- a/code/modules/clothing/chameleon/_chameleon_action.dm +++ b/code/modules/clothing/chameleon/_chameleon_action.dm @@ -208,7 +208,7 @@ if(istype(applying_from, /datum/outfit/job)) var/datum/outfit/job/job_outfit = applying_from - var/datum/job/job_datum = SSjob.GetJobType(job_outfit.jobtype) + var/datum/job/job_datum = SSjob.get_job_type(job_outfit.jobtype) apply_job_data(job_datum) update_look(using_item_type) diff --git a/code/modules/clothing/outfits/event.dm b/code/modules/clothing/outfits/event.dm index fa07b3297b2..b99ea6f5262 100644 --- a/code/modules/clothing/outfits/event.dm +++ b/code/modules/clothing/outfits/event.dm @@ -18,7 +18,7 @@ if(visualsOnly) return user.fully_replace_character_name(user.real_name, "Santa Claus") - user.mind.set_assigned_role(SSjob.GetJobType(/datum/job/santa)) + user.mind.set_assigned_role(SSjob.get_job_type(/datum/job/santa)) user.mind.special_role = ROLE_SANTA user.hairstyle = "Long Hair 3" diff --git a/code/modules/events/ghost_role/fugitive_event.dm b/code/modules/events/ghost_role/fugitive_event.dm index 9eb792a6f6a..f0e1a7c893a 100644 --- a/code/modules/events/ghost_role/fugitive_event.dm +++ b/code/modules/events/ghost_role/fugitive_event.dm @@ -72,7 +72,7 @@ player_mind.active = TRUE var/mob/living/carbon/human/S = new(landing_turf) player_mind.transfer_to(S) - player_mind.set_assigned_role(SSjob.GetJobType(/datum/job/fugitive)) + player_mind.set_assigned_role(SSjob.get_job_type(/datum/job/fugitive)) player_mind.special_role = ROLE_FUGITIVE player_mind.add_antag_datum(/datum/antagonist/fugitive) var/datum/antagonist/fugitive/fugitiveantag = player_mind.has_antag_datum(/datum/antagonist/fugitive) diff --git a/code/modules/events/ghost_role/morph_event.dm b/code/modules/events/ghost_role/morph_event.dm index 21d4b07873d..1b7af6361fd 100644 --- a/code/modules/events/ghost_role/morph_event.dm +++ b/code/modules/events/ghost_role/morph_event.dm @@ -25,7 +25,7 @@ var/mob/living/basic/morph/corpus_accipientis = new(spawn_loc) player_mind.transfer_to(corpus_accipientis) - player_mind.set_assigned_role(SSjob.GetJobType(/datum/job/morph)) + player_mind.set_assigned_role(SSjob.get_job_type(/datum/job/morph)) player_mind.special_role = ROLE_MORPH player_mind.add_antag_datum(/datum/antagonist/morph) SEND_SOUND(corpus_accipientis, sound('sound/magic/mutate.ogg')) diff --git a/code/modules/events/ghost_role/nightmare.dm b/code/modules/events/ghost_role/nightmare.dm index d30108d94b9..1fdebff0cd8 100644 --- a/code/modules/events/ghost_role/nightmare.dm +++ b/code/modules/events/ghost_role/nightmare.dm @@ -27,7 +27,7 @@ var/mob/living/carbon/human/S = new (spawn_loc) player_mind.transfer_to(S) - player_mind.set_assigned_role(SSjob.GetJobType(/datum/job/nightmare)) + player_mind.set_assigned_role(SSjob.get_job_type(/datum/job/nightmare)) player_mind.special_role = ROLE_NIGHTMARE player_mind.add_antag_datum(/datum/antagonist/nightmare) S.set_species(/datum/species/shadow/nightmare) diff --git a/code/modules/events/ghost_role/operative.dm b/code/modules/events/ghost_role/operative.dm index 98cfe5ecad4..c7ad41d001d 100644 --- a/code/modules/events/ghost_role/operative.dm +++ b/code/modules/events/ghost_role/operative.dm @@ -22,7 +22,7 @@ operative.randomize_human_appearance(~RANDOMIZE_SPECIES) operative.dna.update_dna_identity() var/datum/mind/Mind = new /datum/mind(chosen_one.key) - Mind.set_assigned_role(SSjob.GetJobType(/datum/job/lone_operative)) + Mind.set_assigned_role(SSjob.get_job_type(/datum/job/lone_operative)) Mind.special_role = ROLE_LONE_OPERATIVE Mind.active = TRUE Mind.transfer_to(operative) diff --git a/code/modules/events/wizard/rpgtitles.dm b/code/modules/events/wizard/rpgtitles.dm index 9bb69a90f2c..b78ae483ea6 100644 --- a/code/modules/events/wizard/rpgtitles.dm +++ b/code/modules/events/wizard/rpgtitles.dm @@ -38,7 +38,7 @@ GLOBAL_DATUM(rpgtitle_controller, /datum/rpgtitle_controller) /datum/rpgtitle_controller/proc/on_crewmember_join(datum/source, mob/living/new_crewmember, rank) SIGNAL_HANDLER - var/datum/job/job = SSjob.GetJob(rank) + var/datum/job/job = SSjob.get_job(rank) //we must prepare for the mother of all strings new_crewmember.maptext_height = max(new_crewmember.maptext_height, 32) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 81d42b051df..a4f4157c74f 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -381,10 +381,10 @@ if(visualsOnly) return - var/datum/job/equipped_job = SSjob.GetJobType(jobtype) + var/datum/job/equipped_job = SSjob.get_job_type(jobtype) if(!equipped_job) - equipped_job = SSjob.GetJob(equipped.job) + equipped_job = SSjob.get_job(equipped.job) var/obj/item/card/id/card = equipped.wear_id diff --git a/code/modules/jobs/job_types/cook.dm b/code/modules/jobs/job_types/cook.dm index 26a43fa7751..dc36796c4d1 100644 --- a/code/modules/jobs/job_types/cook.dm +++ b/code/modules/jobs/job_types/cook.dm @@ -82,7 +82,7 @@ /datum/outfit/job/cook/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE) ..() - var/datum/job/cook/other_chefs = SSjob.GetJobType(jobtype) + var/datum/job/cook/other_chefs = SSjob.get_job_type(jobtype) if(other_chefs) // If there's other Chefs, you're a Cook if(other_chefs.cooks > 0)//Cooks id_trim = /datum/id_trim/job/cook diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 4db5ae88849..95c2a301765 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -127,7 +127,7 @@ return GENERIC_JOB_UNAVAILABLE_ERROR /mob/dead/new_player/proc/IsJobUnavailable(rank, latejoin = FALSE) - var/datum/job/job = SSjob.GetJob(rank) + var/datum/job/job = SSjob.get_job(rank) if(!(job.job_flags & JOB_NEW_PLAYER_JOINABLE)) return JOB_UNAVAILABLE_GENERIC if((job.current_positions >= job.total_positions) && job.total_positions != -1) @@ -172,9 +172,9 @@ SSticker.queued_players -= src SSticker.queue_delay = 4 - var/datum/job/job = SSjob.GetJob(rank) + var/datum/job/job = SSjob.get_job(rank) - if(!SSjob.AssignRole(src, job, TRUE)) + if(!SSjob.assign_role(src, job, TRUE)) tgui_alert(usr, "There was an unexpected error putting you into your requested job. If you cannot join with any job, you should contact an admin.") return FALSE @@ -187,7 +187,7 @@ CRASH("Failed to create a character for latejoin.") transfer_character() - SSjob.EquipRank(character, job, character.client) + SSjob.equip_rank(character, job, character.client) job.after_latejoin_spawn(character) #define IS_NOT_CAPTAIN 0 diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index 49ac17d48ec..fb3b97066e0 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -88,13 +88,13 @@ for(var/job in job_preferences) if(job_preferences[job] > highest_pref) - preview_job = SSjob.GetJob(job) + preview_job = SSjob.get_job(job) highest_pref = job_preferences[job] return preview_job /datum/preferences/proc/render_new_preview_appearance(mob/living/carbon/human/dummy/mannequin, show_job_clothes = TRUE) - var/datum/job/no_job = SSjob.GetJobType(/datum/job/unassigned) + var/datum/job/no_job = SSjob.get_job_type(/datum/job/unassigned) var/datum/job/preview_job = get_highest_priority_job() || no_job if(preview_job) diff --git a/code/modules/mob/living/basic/space_fauna/demon/demon.dm b/code/modules/mob/living/basic/space_fauna/demon/demon.dm index 21eaf66a3e8..eb424cdce49 100644 --- a/code/modules/mob/living/basic/space_fauna/demon/demon.dm +++ b/code/modules/mob/living/basic/space_fauna/demon/demon.dm @@ -66,7 +66,7 @@ if(isnull(antag_type) || mind.has_antag_datum(antag_type)) return // we weren't built for this proc to run - mind.set_assigned_role(SSjob.GetJobType(/datum/job/slaughter_demon)) + mind.set_assigned_role(SSjob.get_job_type(/datum/job/slaughter_demon)) mind.special_role = ROLE_SLAUGHTER_DEMON mind.add_antag_datum(antag_type) diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm index a154ba9da0c..62b6a8da7e6 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -125,7 +125,7 @@ return TRUE generated_objectives_and_spells = TRUE - mind.set_assigned_role(SSjob.GetJobType(/datum/job/revenant)) + mind.set_assigned_role(SSjob.get_job_type(/datum/job/revenant)) mind.special_role = ROLE_REVENANT SEND_SOUND(src, sound('sound/effects/ghost.ogg')) mind.add_antag_datum(/datum/antagonist/revenant) diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index 7d4255d54d5..04967c76731 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -137,7 +137,7 @@ GLOBAL_VAR(posibrain_notify_cooldown) brainmob.timeofdeath = transferred_user.timeofdeath brainmob.set_stat(CONSCIOUS) if(brainmob.mind) - brainmob.mind.set_assigned_role(SSjob.GetJobType(posibrain_job_path)) + brainmob.mind.set_assigned_role(SSjob.get_job_type(posibrain_job_path)) if(transferred_user.mind) transferred_user.mind.transfer_to(brainmob) @@ -160,7 +160,7 @@ GLOBAL_VAR(posibrain_notify_cooldown) var/policy = get_policy(ROLE_POSIBRAIN) if(policy) to_chat(brainmob, policy) - brainmob.mind.set_assigned_role(SSjob.GetJobType(posibrain_job_path)) + brainmob.mind.set_assigned_role(SSjob.get_job_type(posibrain_job_path)) brainmob.set_stat(CONSCIOUS) visible_message(new_mob_message) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 84b2aa8534d..3e2248914dc 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -317,7 +317,7 @@ clone.pitch = pitch dna.transfer_identity(clone, transfer_SE = TRUE, transfer_species = TRUE) - clone.dress_up_as_job(SSjob.GetJob(job)) + clone.dress_up_as_job(SSjob.get_job(job)) for(var/datum/quirk/original_quircks as anything in quirks) clone.add_quirk(original_quircks.type, override_client = client) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 30b3254603b..f0712766fa6 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -1186,7 +1186,7 @@ /mob/living/silicon/ai/get_exp_list(minutes) . = ..() - var/datum/job/ai/ai_job_ref = SSjob.GetJobType(/datum/job/ai) + var/datum/job/ai/ai_job_ref = SSjob.get_job_type(/datum/job/ai) .[ai_job_ref.title] = minutes diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index dc6f449bdb4..04de7c928e1 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1015,7 +1015,7 @@ /mob/living/silicon/robot/get_exp_list(minutes) . = ..() - var/datum/job/cyborg/cyborg_job_ref = SSjob.GetJobType(/datum/job/cyborg) + var/datum/job/cyborg/cyborg_job_ref = SSjob.get_job_type(/datum/job/cyborg) .[cyborg_job_ref.title] = minutes diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index cde5ecdbc05..d09de265dda 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -356,7 +356,7 @@ for(var/obj/item/to_strip in new_clown.get_equipped_items()) new_clown.dropItemToGround(to_strip) - new_clown.dress_up_as_job(SSjob.GetJobType(/datum/job/clown)) + new_clown.dress_up_as_job(SSjob.get_job_type(/datum/job/clown)) clowned_mob_refs += clown_ref return TRUE diff --git a/code/modules/mob_spawn/ghost_roles/unused_roles.dm b/code/modules/mob_spawn/ghost_roles/unused_roles.dm index 80f584d52c2..d533c2365c4 100644 --- a/code/modules/mob_spawn/ghost_roles/unused_roles.dm +++ b/code/modules/mob_spawn/ghost_roles/unused_roles.dm @@ -273,7 +273,7 @@ /obj/effect/mob_spawn/ghost_role/human/syndicatespace/special(mob/living/new_spawn) . = ..() new_spawn.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND) - var/datum/job/spawn_job = SSjob.GetJobType(spawner_job_path) + var/datum/job/spawn_job = SSjob.get_job_type(spawner_job_path) var/policy = get_policy(spawn_job.policy_index) if(policy) to_chat(new_spawn, span_bold("[policy]")) diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm index 36562cec6e8..b70b89a4da1 100644 --- a/code/modules/mob_spawn/mob_spawn.dm +++ b/code/modules/mob_spawn/mob_spawn.dm @@ -245,7 +245,7 @@ spawned_mob.key = mob_possessor.key var/datum/mind/spawned_mind = spawned_mob.mind if(spawned_mind) - spawned_mob.mind.set_assigned_role_with_greeting(SSjob.GetJobType(spawner_job_path)) + spawned_mob.mind.set_assigned_role_with_greeting(SSjob.get_job_type(spawner_job_path)) spawned_mind.name = spawned_mob.real_name if(show_flavor) diff --git a/code/modules/modular_computers/file_system/programs/jobmanagement.dm b/code/modules/modular_computers/file_system/programs/jobmanagement.dm index 8d4db5ffb08..2d518408863 100644 --- a/code/modules/modular_computers/file_system/programs/jobmanagement.dm +++ b/code/modules/modular_computers/file_system/programs/jobmanagement.dm @@ -62,7 +62,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) switch(action) if("PRG_open_job") var/edit_job_target = params["target"] - var/datum/job/j = SSjob.GetJob(edit_job_target) + var/datum/job/j = SSjob.get_job(edit_job_target) if(!can_edit_job(j) || !can_open_job(j)) return TRUE if(opened_positions[edit_job_target] >= 0) @@ -74,7 +74,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) return TRUE if("PRG_close_job") var/edit_job_target = params["target"] - var/datum/job/j = SSjob.GetJob(edit_job_target) + var/datum/job/j = SSjob.get_job(edit_job_target) if(!can_edit_job(j) || !can_close_job(j)) return TRUE //Allow instant closing without cooldown if a position has been opened before @@ -87,7 +87,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) return TRUE if("PRG_priority") var/priority_target = params["target"] - var/datum/job/j = SSjob.GetJob(priority_target) + var/datum/job/j = SSjob.get_job(priority_target) if(!can_edit_job(j)) return TRUE if(j.total_positions <= j.current_positions) diff --git a/code/modules/spells/spell_types/self/mime_vow.dm b/code/modules/spells/spell_types/self/mime_vow.dm index d4e34880b53..3d1c44dabd6 100644 --- a/code/modules/spells/spell_types/self/mime_vow.dm +++ b/code/modules/spells/spell_types/self/mime_vow.dm @@ -32,6 +32,6 @@ cast_on.log_message("broke [cast_on.p_their()] vow of silence.", LOG_GAME) cast_on.add_mood_event("vow", /datum/mood_event/broken_vow) REMOVE_TRAIT(cast_on, TRAIT_MIMING, "[type]") - var/datum/job/mime/mime_job = SSjob.GetJob(JOB_MIME) + var/datum/job/mime/mime_job = SSjob.get_job(JOB_MIME) mime_job.total_positions += 1 qdel(src) diff --git a/code/modules/unit_tests/anonymous_themes.dm b/code/modules/unit_tests/anonymous_themes.dm index a58f60eab3b..99cd4f82802 100644 --- a/code/modules/unit_tests/anonymous_themes.dm +++ b/code/modules/unit_tests/anonymous_themes.dm @@ -12,7 +12,7 @@ client.prefs.write_preference(GLOB.preference_entries[/datum/preference/name/real_name], "Prefs Biddle") - human.apply_prefs_job(client, SSjob.GetJobType(/datum/job/assistant)) + human.apply_prefs_job(client, SSjob.get_job_type(/datum/job/assistant)) TEST_ASSERT_NOTEQUAL(human.real_name, "Prefs Biddle", "apply_prefs_job didn't randomize human name with an anonymous theme") TEST_ASSERT_EQUAL(client.prefs.read_preference(/datum/preference/name/real_name), "Prefs Biddle", "Anonymous theme overrode original prefs") diff --git a/code/modules/unit_tests/dummy_spawn.dm b/code/modules/unit_tests/dummy_spawn.dm index ed359f962b7..6ec59eaaa50 100644 --- a/code/modules/unit_tests/dummy_spawn.dm +++ b/code/modules/unit_tests/dummy_spawn.dm @@ -16,7 +16,7 @@ /datum/unit_test/dummy_spawn_outfit/Run() var/mob/living/carbon/human/dummy/lad = allocate(/mob/living/carbon/human/dummy) for(var/datum/job/one_two_three as anything in subtypesof(/datum/job)) - var/datum/job/can_you_hear_this = SSjob.GetJobType(one_two_three) + var/datum/job/can_you_hear_this = SSjob.get_job_type(one_two_three) if(!can_you_hear_this) log_test("\tJob type [one_two_three] could not be retrieved from SSjob") continue diff --git a/code/modules/unit_tests/security_officer_distribution.dm b/code/modules/unit_tests/security_officer_distribution.dm index e268aab709f..05d62eeab35 100644 --- a/code/modules/unit_tests/security_officer_distribution.dm +++ b/code/modules/unit_tests/security_officer_distribution.dm @@ -68,7 +68,7 @@ var/mob/living/carbon/human/new_character = allocate(/mob/living/carbon/human/consistent) new_character.mind_initialize() - new_character.mind.set_assigned_role(SSjob.GetJobType(/datum/job/security_officer)) + new_character.mind.set_assigned_role(SSjob.get_job_type(/datum/job/security_officer)) new_player.new_character = new_character new_player.mock_client = mock_client diff --git a/code/modules/unit_tests/traitor.dm b/code/modules/unit_tests/traitor.dm index 012370d9356..974888b3a0d 100644 --- a/code/modules/unit_tests/traitor.dm +++ b/code/modules/unit_tests/traitor.dm @@ -11,7 +11,7 @@ possible_jobs += rank for(var/job_name in possible_jobs) - var/datum/job/job = SSjob.GetJob(job_name) + var/datum/job/job = SSjob.get_job(job_name) var/mob/living/player = allocate(job.spawn_type) player.mind_initialize() var/datum/mind/mind = player.mind diff --git a/code/modules/unit_tests/traitor_mail_content_check.dm b/code/modules/unit_tests/traitor_mail_content_check.dm index 6d14d9d1428..b2ecfe2ef24 100644 --- a/code/modules/unit_tests/traitor_mail_content_check.dm +++ b/code/modules/unit_tests/traitor_mail_content_check.dm @@ -5,6 +5,6 @@ var/mob/living/carbon/human/person = allocate(/mob/living/carbon/human/consistent) person.mind_initialize() var/obj/item/mail/traitor/test_mail = allocate(/obj/item/mail/traitor) - person.mind.set_assigned_role(SSjob.GetJobType(/datum/job/captain)) + person.mind.set_assigned_role(SSjob.get_job_type(/datum/job/captain)) test_mail.initialize_for_recipient(person.mind) TEST_ASSERT_EQUAL(test_mail.contents.len, 0, "/obj/item/mail/traitor should not have items after initialize_for_recipient proc!")