mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
[MIRROR] Overhauls job eligibility checking and improves job debug logging. [MDB IGNORE] (#9348)
* Overhauls job eligibility checking and improves job debug logging. * Fixing conflicts * Makes Veteran the first check since it's the most likely. Co-authored-by: Timberpoes <silent_insomnia_pp@hotmail.co.uk> Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
This commit is contained in:
co-authored by
Timberpoes
GoldenAlpharex
parent
ec31da7756
commit
08bd01ea3d
@@ -4,6 +4,8 @@
|
||||
#define JOB_UNAVAILABLE_PLAYTIME 3
|
||||
#define JOB_UNAVAILABLE_ACCOUNTAGE 4
|
||||
#define JOB_UNAVAILABLE_SLOTFULL 5
|
||||
/// Job unavailable due to incompatibility with an antag role.
|
||||
#define JOB_UNAVAILABLE_ANTAG_INCOMPAT 6
|
||||
|
||||
#define DEFAULT_RELIGION "Christianity"
|
||||
#define DEFAULT_DEITY "Space Jesus"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#define JOB_UNAVAILABLE_QUIRK 6
|
||||
#define JOB_UNAVAILABLE_SPECIES 7
|
||||
#define JOB_UNAVAILABLE_LANGUAGE 7
|
||||
#define JOB_NOT_VETERAN 8
|
||||
// Just keeping this easy to maintain in the future.
|
||||
#define JOB_NOT_VETERAN JOB_UNAVAILABLE_GENERIC + 1
|
||||
#define JOB_UNAVAILABLE_QUIRK JOB_NOT_VETERAN + 1
|
||||
#define JOB_UNAVAILABLE_SPECIES JOB_UNAVAILABLE_QUIRK + 1
|
||||
#define JOB_UNAVAILABLE_LANGUAGE JOB_UNAVAILABLE_SPECIES + 1
|
||||
|
||||
#define SEC_RESTRICTED_QUIRKS "Blind" = TRUE, "Brain Tumor" = TRUE, "Deaf" = TRUE, "Paraplegic" = TRUE, "Mute" = TRUE, "Foreigner" = TRUE, "Pacifist" = TRUE, "Chunky Fingers" = TRUE, "Nymphomania" = TRUE
|
||||
#define HEAD_RESTRICTED_QUIRKS "Blind" = TRUE, "Deaf" = TRUE, "Mute" = TRUE, "Foreigner" = TRUE, "Chunky Fingers" = TRUE, "Nymphomania" = TRUE
|
||||
|
||||
+182
-147
@@ -67,6 +67,8 @@ SUBSYSTEM_DEF(job)
|
||||
/// The loc to which the emergency safe code has been requested for delivery.
|
||||
var/turf/safe_code_request_loc
|
||||
|
||||
/// Dictionary that maps job priorities to low/medium/high. Keys have to be number-strings as assoc lists cannot be indexed by integers. Set in setup_job_lists.
|
||||
var/list/job_priorities_to_strings
|
||||
|
||||
/datum/controller/subsystem/job/Initialize(timeofday)
|
||||
setup_job_lists()
|
||||
@@ -184,38 +186,30 @@ SUBSYSTEM_DEF(job)
|
||||
SetupOccupations()
|
||||
return joinable_departments_by_type[department_type]
|
||||
|
||||
|
||||
/datum/controller/subsystem/job/proc/AssignRole(mob/dead/new_player/player, datum/job/job, latejoin = FALSE)
|
||||
JobDebug("Running AR, Player: [player], Rank: [isnull(job) ? "null" : job.type], LJ: [latejoin]")
|
||||
/**
|
||||
* Assigns the given job role to the player.
|
||||
*
|
||||
* Arguments:
|
||||
* * player - The player to assign the job to
|
||||
* * job - The job to assign
|
||||
* * 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]")
|
||||
if(!player?.mind || !job)
|
||||
JobDebug("AR has failed, Player: [player], Rank: [isnull(job) ? "null" : job.type]")
|
||||
JobDebug("AR has failed, player has no mind or job is null, Player: [player], Rank: [isnull(job) ? "null" : job.type]")
|
||||
return FALSE
|
||||
if(is_banned_from(player.ckey, job.title) || QDELETED(player))
|
||||
|
||||
if(do_eligibility_checks && (check_job_eligibility(player, job, "AR", add_job_to_log = TRUE) != JOB_AVAILABLE))
|
||||
return FALSE
|
||||
if(!job.player_old_enough(player.client))
|
||||
return FALSE
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
return FALSE
|
||||
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
|
||||
if(job.has_banned_quirk(player.client.prefs))
|
||||
return FALSE
|
||||
if(!job.has_required_languages(player.client.prefs))
|
||||
return FALSE
|
||||
if(job.veteran_only && !is_veteran_player(player.client))
|
||||
return FALSE
|
||||
if(job.has_banned_species(player.client.prefs))
|
||||
return FALSE
|
||||
//SKYRAT EDIT END
|
||||
var/position_limit = job.total_positions
|
||||
if(!latejoin)
|
||||
position_limit = job.spawn_positions
|
||||
JobDebug("Player: [player] is now Rank: [job.title], JCP:[job.current_positions], JPL:[position_limit]")
|
||||
|
||||
JobDebug("Player: [player] is now Rank: [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/FreeRole(rank)
|
||||
if(!rank)
|
||||
return
|
||||
@@ -225,42 +219,26 @@ SUBSYSTEM_DEF(job)
|
||||
return FALSE
|
||||
job.current_positions = max(0, job.current_positions - 1)
|
||||
|
||||
/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/job/job, level, flag)
|
||||
JobDebug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
|
||||
/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/job/job, level)
|
||||
JobDebug("Running FOC, Job: [job], Level: [job_priority_level_to_string(level)]")
|
||||
var/list/candidates = list()
|
||||
for(var/mob/dead/new_player/player in unassigned)
|
||||
if(is_banned_from(player.ckey, job.title) || QDELETED(player))
|
||||
JobDebug("FOC isbanned failed, Player: [player]")
|
||||
// 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
|
||||
if(!job.player_old_enough(player.client))
|
||||
JobDebug("FOC player not old enough, Player: [player]")
|
||||
continue
|
||||
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
|
||||
if(job.has_banned_quirk(player.client.prefs))
|
||||
JobDebug("FOC job not compatible with quirks, Player: [player]")
|
||||
continue
|
||||
if(!job.has_required_languages(player.client.prefs))
|
||||
JobDebug("FOC job not compatible with languages, Player: [player]")
|
||||
continue
|
||||
if(job.veteran_only && !is_veteran_player(player.client))
|
||||
JobDebug("FOC player is not veteran, Player: [player]")
|
||||
if(job.has_banned_species(player.client.prefs))
|
||||
JobDebug("FOC job not compatible with species, Player: [player]")
|
||||
continue
|
||||
//SKYRAT EDIT END
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
JobDebug("FOC player not enough xp, Player: [player]")
|
||||
continue
|
||||
if(flag && (!(flag in player.client.prefs.be_special)))
|
||||
JobDebug("FOC flag failed, Player: [player], Flag: [flag], ")
|
||||
continue
|
||||
if(player.mind && (job.title in player.mind.restricted_roles))
|
||||
JobDebug("FOC incompatible with antagonist role, Player: [player]")
|
||||
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)]")
|
||||
continue
|
||||
|
||||
if(player.client.prefs.job_preferences[job.title] == level)
|
||||
JobDebug("FOC pass, Player: [player], Level:[level]")
|
||||
candidates += player
|
||||
// This check handles its own output to JobDebug.
|
||||
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)]")
|
||||
candidates += player
|
||||
return candidates
|
||||
|
||||
|
||||
@@ -268,55 +246,36 @@ SUBSYSTEM_DEF(job)
|
||||
JobDebug("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")
|
||||
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]")
|
||||
|
||||
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]")
|
||||
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]")
|
||||
continue
|
||||
|
||||
//SKYRAT EDIT ADDITION
|
||||
if(job.departments_bitflags & DEPARTMENT_BITFLAG_CENTRAL_COMMAND) //If you want a CC position, select it!
|
||||
JobDebug("GRJ skipping Central Command role, Player: [player], Job: [job]")
|
||||
continue
|
||||
//SKYRAT EDIT END
|
||||
|
||||
if(is_banned_from(player.ckey, job.title) || QDELETED(player))
|
||||
if(QDELETED(player))
|
||||
JobDebug("GRJ isbanned failed, Player deleted")
|
||||
break
|
||||
JobDebug("GRJ isbanned failed, Player: [player], Job: [job.title]")
|
||||
|
||||
// This check handles its own output to JobDebug.
|
||||
if(check_job_eligibility(player, job, "GRJ", add_job_to_log = TRUE) != JOB_AVAILABLE)
|
||||
continue
|
||||
|
||||
if(!job.player_old_enough(player.client))
|
||||
JobDebug("GRJ player not old enough, Player: [player]")
|
||||
continue
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
|
||||
if(job.has_banned_quirk(player.client.prefs))
|
||||
JobDebug("GRJ player has incompatible quirk, Player: [player]")
|
||||
continue
|
||||
if(!job.has_required_languages(player.client.prefs))
|
||||
JobDebug("GRJ player has incompatible languages, Player: [player]")
|
||||
continue
|
||||
if(job.veteran_only && !is_veteran_player(player.client))
|
||||
JobDebug("GRJ player is not veteran, Player: [player]")
|
||||
if(job.has_banned_species(player.client.prefs))
|
||||
JobDebug("GRJ player has incompatible species, Player: [player]")
|
||||
continue
|
||||
//SKYRAT EDIT END
|
||||
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
JobDebug("GRJ player not enough xp, Player: [player]")
|
||||
continue
|
||||
|
||||
if(player.mind && (job.title in player.mind.restricted_roles))
|
||||
JobDebug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]")
|
||||
continue
|
||||
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
if(AssignRole(player, job, do_eligibility_checks = FALSE))
|
||||
JobDebug("GRJ Random job given, Player: [player], Job: [job]")
|
||||
if(AssignRole(player, job))
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
JobDebug("GRJ Player eligible but AssignRole failed, Player: [player], Job: [job]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/job/proc/ResetOccupations()
|
||||
@@ -331,9 +290,11 @@ SUBSYSTEM_DEF(job)
|
||||
return
|
||||
|
||||
|
||||
//This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until
|
||||
//it locates a head or runs out of levels to check
|
||||
//This is basically to ensure that there's atleast a few heads in the round
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
/datum/controller/subsystem/job/proc/FillHeadPosition()
|
||||
var/datum/job_department/command_department = get_department_type(/datum/job_department/command)
|
||||
if(!command_department)
|
||||
@@ -346,13 +307,18 @@ SUBSYSTEM_DEF(job)
|
||||
if(!candidates.len)
|
||||
continue
|
||||
var/mob/dead/new_player/candidate = pick(candidates)
|
||||
if(AssignRole(candidate, job))
|
||||
// Eligibility checks done as part of FindOccupationCandidates.
|
||||
if(AssignRole(candidate, job, do_eligibility_checks = FALSE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
//This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level
|
||||
//This is also to ensure we get as many heads as possible
|
||||
/**
|
||||
* Attempts to fill out all possible head positions for players with that job at a a given job priority level.
|
||||
*
|
||||
* Arguments:
|
||||
* * level - One of the JP_LOW, JP_MEDIUM or JP_HIGH defines. Attempts to find candidates with head jobs at this priority only.
|
||||
*/
|
||||
/datum/controller/subsystem/job/proc/CheckHeadPositions(level)
|
||||
var/datum/job_department/command_department = get_department_type(/datum/job_department/command)
|
||||
if(!command_department)
|
||||
@@ -364,7 +330,8 @@ SUBSYSTEM_DEF(job)
|
||||
if(!candidates.len)
|
||||
continue
|
||||
var/mob/dead/new_player/candidate = pick(candidates)
|
||||
AssignRole(candidate, job)
|
||||
// Eligibility checks done as part of FindOccupationCandidates
|
||||
AssignRole(candidate, job, do_eligibility_checks = FALSE)
|
||||
|
||||
/// Attempts to fill out all available AI positions.
|
||||
/datum/controller/subsystem/job/proc/fill_ai_positions()
|
||||
@@ -378,7 +345,8 @@ SUBSYSTEM_DEF(job)
|
||||
candidates = FindOccupationCandidates(ai_job, level)
|
||||
if(candidates.len)
|
||||
var/mob/dead/new_player/candidate = pick(candidates)
|
||||
if(AssignRole(candidate, GetJobType(/datum/job/ai)))
|
||||
// Eligibility checks done as part of FindOccupationCandidates
|
||||
if(AssignRole(candidate, GetJobType(/datum/job/ai), do_eligibility_checks = FALSE))
|
||||
break
|
||||
|
||||
|
||||
@@ -429,7 +397,8 @@ SUBSYSTEM_DEF(job)
|
||||
JobDebug("AC1, Candidates: [overflow_candidates.len]")
|
||||
for(var/mob/dead/new_player/player in overflow_candidates)
|
||||
JobDebug("AC1 pass, Player: [player]")
|
||||
AssignRole(player, GetJobType(overflow_role))
|
||||
// Eligibility checks done as part of FindOccupationCandidates
|
||||
AssignRole(player, GetJobType(overflow_role), do_eligibility_checks = FALSE)
|
||||
overflow_candidates -= player
|
||||
JobDebug("DO, AC1 end")
|
||||
|
||||
@@ -444,9 +413,7 @@ SUBSYSTEM_DEF(job)
|
||||
JobDebug("DO, AI Check end")
|
||||
|
||||
//Other jobs are now checked
|
||||
JobDebug("DO, Running Standard Check")
|
||||
|
||||
|
||||
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.
|
||||
@@ -465,65 +432,54 @@ SUBSYSTEM_DEF(job)
|
||||
// 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
|
||||
|
||||
if(is_banned_from(player.ckey, job.title))
|
||||
JobDebug("DO isbanned failed, Player: [player], Job:[job.title]")
|
||||
// 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
|
||||
|
||||
if(QDELETED(player))
|
||||
JobDebug("DO player deleted during job ban check")
|
||||
break
|
||||
|
||||
if(!job.player_old_enough(player.client))
|
||||
JobDebug("DO player not old enough, Player: [player], Job:[job.title]")
|
||||
// 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]")
|
||||
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)]")
|
||||
continue
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
|
||||
if(job.has_banned_quirk(player.client.prefs))
|
||||
JobDebug("DO player has incompatible quirk, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
if(!job.has_required_languages(player.client.prefs))
|
||||
JobDebug("DO player has incompatible languages, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
if(job.veteran_only && !is_veteran_player(player.client))
|
||||
JobDebug("DO player is not veteran, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
if(job.has_banned_species(player.client.prefs))
|
||||
JobDebug("DO player has incompatible species, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
//SKYRAT EDIT END
|
||||
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
JobDebug("DO player not enough xp, Player: [player], Job:[job.title]")
|
||||
if(check_job_eligibility(player, job, "DO", add_job_to_log = TRUE) != JOB_AVAILABLE)
|
||||
continue
|
||||
|
||||
if(player.mind && (job.title in player.mind.restricted_roles))
|
||||
JobDebug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
JobDebug("DO pass, Player: [player], Level:[level], Job:[job.title]")
|
||||
AssignRole(player, job, do_eligibility_checks = FALSE)
|
||||
unassigned -= player
|
||||
break
|
||||
|
||||
// If the player wants that job on this level, then try give it to him.
|
||||
if(player.client.prefs.job_preferences[job.title] == level)
|
||||
// If the job isn't filled
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
JobDebug("DO pass, Player: [player], Level:[level], Job:[job.title]")
|
||||
AssignRole(player, job)
|
||||
unassigned -= player
|
||||
break
|
||||
JobDebug("DO, Ending standard job assignment")
|
||||
|
||||
|
||||
JobDebug("DO, Handling unassigned.")
|
||||
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
|
||||
for(var/mob/dead/new_player/player in unassigned)
|
||||
HandleUnassigned(player)
|
||||
JobDebug("DO, Ending handle unassigned.")
|
||||
|
||||
JobDebug("DO, Handling unrejectable unassigned")
|
||||
JobDebug("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("---------------------------------------------------")
|
||||
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")
|
||||
|
||||
JobDebug("All divide occupations tasks completed.")
|
||||
JobDebug("---------------------------------------------------")
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -538,19 +494,23 @@ SUBSYSTEM_DEF(job)
|
||||
switch (jobless_role)
|
||||
if (BEOVERFLOW)
|
||||
var/datum/job/overflow_role_datum = GetJobType(overflow_role)
|
||||
var/allowed_to_be_a_loser = !is_banned_from(player.ckey, overflow_role_datum.title)
|
||||
if(QDELETED(player) || !allowed_to_be_a_loser)
|
||||
|
||||
if(check_job_eligibility(player, overflow_role_datum, debug_prefix = "HU", add_job_to_log = TRUE) != JOB_AVAILABLE)
|
||||
RejectPlayer(player)
|
||||
else
|
||||
if(!AssignRole(player, overflow_role_datum))
|
||||
RejectPlayer(player)
|
||||
return
|
||||
|
||||
if(!AssignRole(player, overflow_role_datum, do_eligibility_checks = FALSE))
|
||||
RejectPlayer(player)
|
||||
return
|
||||
if (BERANDOMJOB)
|
||||
if(!GiveRandomJob(player))
|
||||
RejectPlayer(player)
|
||||
return
|
||||
if (RETURNTOLOBBY)
|
||||
RejectPlayer(player)
|
||||
return
|
||||
else //Something gone wrong if we got here.
|
||||
var/message = "DO: [player] fell through handling unassigned"
|
||||
var/message = "HU: [player] fell through handling unassigned"
|
||||
JobDebug(message)
|
||||
log_game(message)
|
||||
message_admins(message)
|
||||
@@ -854,6 +814,12 @@ SUBSYSTEM_DEF(job)
|
||||
"Special Ops Officer", "Admiral", "CentCom Commander", "CentCom Bartender", "Private Security Force", "Fleetmaster", "Bridge Officer", "Operations Inspector", \
|
||||
"Deck Crewman")
|
||||
|
||||
job_priorities_to_strings = list(
|
||||
"[JP_LOW]" = "Low Priority",
|
||||
"[JP_MEDIUM]" = "Medium Priority",
|
||||
"[JP_HIGH]" = "High Priority",
|
||||
)
|
||||
|
||||
/obj/item/paper/fluff/spare_id_safe_code
|
||||
name = "Nanotrasen-Approved Spare ID Safe Code"
|
||||
desc = "Proof that you have been approved for Captaincy, with all its glory and all its horror."
|
||||
@@ -914,4 +880,73 @@ SUBSYSTEM_DEF(job)
|
||||
/// Blindly assigns the required roles to every player in the dynamic_forced_occupations list.
|
||||
/datum/controller/subsystem/job/proc/assign_priority_positions()
|
||||
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]))
|
||||
|
||||
/// 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)
|
||||
return job_priorities_to_strings["[priority]"] || "Undefined Priority \[[priority]\]"
|
||||
|
||||
/**
|
||||
* Runs a standard suite of eligibility checks to make sure the player can take the reqeusted job.
|
||||
*
|
||||
* Checks:
|
||||
* * Role bans
|
||||
* * How many days old the player account is
|
||||
* * Whether the player has the required hours in other jobs to take that role
|
||||
* * If the job is in the mind's restricted roles, for example if they have an antag datum that's incompatible with certain roles.
|
||||
*
|
||||
* 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.
|
||||
* * 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]" : ""]")
|
||||
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)], 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)], 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)], 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)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]")
|
||||
return JOB_UNAVAILABLE_BANNED
|
||||
|
||||
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
|
||||
if(possible_job.veteran_only && !is_veteran_player(player.client))
|
||||
JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_NOT_VETERAN)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]")
|
||||
return JOB_NOT_VETERAN
|
||||
|
||||
if(possible_job.has_banned_quirk(player.client.prefs))
|
||||
JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_QUIRK)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]")
|
||||
return JOB_UNAVAILABLE_QUIRK
|
||||
|
||||
if(!possible_job.has_required_languages(player.client.prefs))
|
||||
JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_LANGUAGE)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]")
|
||||
return JOB_UNAVAILABLE_LANGUAGE
|
||||
|
||||
if(possible_job.has_banned_species(player.client.prefs))
|
||||
JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_SPECIES)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]")
|
||||
return JOB_UNAVAILABLE_SPECIES
|
||||
//SKYRAT EDIT END
|
||||
|
||||
// Run this check 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]" : ""]")
|
||||
return JOB_UNAVAILABLE_GENERIC
|
||||
|
||||
return JOB_AVAILABLE
|
||||
|
||||
@@ -230,7 +230,8 @@
|
||||
var/exclusive_candidate = FALSE
|
||||
for(var/role in exclusive_roles)
|
||||
var/datum/job/job = SSjob.GetJob(role)
|
||||
if((role in candidate_client.prefs.job_preferences) && !is_banned_from(candidate_player.ckey, role) && !job.required_playtime_remaining(candidate_client))
|
||||
|
||||
if((role in candidate_client.prefs.job_preferences) && SSjob.check_job_eligibility(candidate_player, job, "Dynamic Roundstart TC", add_job_to_log = TRUE))
|
||||
exclusive_candidate = TRUE
|
||||
break
|
||||
|
||||
|
||||
@@ -150,15 +150,17 @@
|
||||
if(JOB_UNAVAILABLE_SLOTFULL)
|
||||
return "[jobtitle] is already filled to capacity."
|
||||
//SKYRAT EDIT ADDITION
|
||||
if(JOB_NOT_VETERAN)
|
||||
return "You need to be veteran to join as [jobtitle]."
|
||||
if(JOB_UNAVAILABLE_QUIRK)
|
||||
return "[jobtitle] is restricted from your quirks."
|
||||
if(JOB_UNAVAILABLE_LANGUAGE)
|
||||
return "[jobtitle] is restricted from your languages."
|
||||
if(JOB_NOT_VETERAN)
|
||||
return "You need to be veteran to join as [jobtitle]."
|
||||
if(JOB_UNAVAILABLE_SPECIES)
|
||||
return "[jobtitle] is restricted from your species."
|
||||
//SKYRAT EDIT END
|
||||
if(JOB_UNAVAILABLE_ANTAG_INCOMPAT)
|
||||
return "[jobtitle] is not compatible with some antagonist role assigned to you."
|
||||
return "Error: Unknown job availability."
|
||||
|
||||
/mob/dead/new_player/proc/IsJobUnavailable(rank, latejoin = FALSE)
|
||||
@@ -174,14 +176,11 @@
|
||||
return JOB_UNAVAILABLE_SLOTFULL
|
||||
else
|
||||
return JOB_UNAVAILABLE_SLOTFULL
|
||||
if(is_banned_from(ckey, rank))
|
||||
return JOB_UNAVAILABLE_BANNED
|
||||
if(QDELETED(src))
|
||||
return JOB_UNAVAILABLE_GENERIC
|
||||
if(!job.player_old_enough(client))
|
||||
return JOB_UNAVAILABLE_ACCOUNTAGE
|
||||
if(job.required_playtime_remaining(client))
|
||||
return JOB_UNAVAILABLE_PLAYTIME
|
||||
|
||||
var/eligibility_check = SSjob.check_job_eligibility(src, job, "Mob IsJobUnavailable")
|
||||
if(eligibility_check != JOB_AVAILABLE)
|
||||
return eligibility_check
|
||||
|
||||
if(latejoin && !job.special_check_latejoin(client))
|
||||
return JOB_UNAVAILABLE_GENERIC
|
||||
//SKYRAT EDIT ADDITION
|
||||
@@ -217,7 +216,9 @@
|
||||
|
||||
var/datum/job/job = SSjob.GetJob(rank)
|
||||
|
||||
SSjob.AssignRole(src, job, TRUE)
|
||||
if(!SSjob.AssignRole(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
|
||||
|
||||
mind.late_joiner = TRUE
|
||||
var/atom/destination = mind.assigned_role.get_latejoin_spawn_point()
|
||||
|
||||
Reference in New Issue
Block a user