diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index fc467d4f71..4c9c3b5822 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -23,8 +23,10 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
economic_modifier = 20
minimum_character_age = 25
- min_age_by_species = list(SPECIES_UNATHI = 70, SPECIES_TESHARI = 20, "mechanical" = 10)
-/// ideal_character_age = 70 // Old geezer captains ftw
+ min_age_by_species = list(SPECIES_HUMAN_VATBORN = 12)
+ ideal_character_age = 70 // Old geezer captains ftw
+ ideal_age_by_species = list(SPECIES_HUMAN_VATBORN = 55) /// Vatborn live shorter, no other race eligible for captain besides human/skrell
+ banned_job_species = list(SPECIES_UNATHI, SPECIES_TAJ, SPECIES_DIONA, SPECIES_PROMETHEAN, SPECIES_ZADDAT, "mechanical", "digital")
outfit_type = /decl/hierarchy/outfit/job/captain
job_description = "The Site Manager manages the other Command Staff, and through them the rest of the station. Though they have access to everything, \
@@ -68,8 +70,10 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
economic_modifier = 10
minimum_character_age = 25
- min_age_by_species = list(SPECIES_UNATHI = 70, SPECIES_TESHARI = 20, "mechanical" = 10)
-/// ideal_character_age = 50
+ min_age_by_species = list(SPECIES_UNATHI = 70, SPECIES_TESHARI = 20, "mechanical" = 10, SPECIES_HUMAN_VATBORN = 12)
+ ideal_character_age = 50
+ ideal_age_by_species = list(SPECIES_UNATHI = 140, SPECIES_TESHARI = 27, "mechanical" = 20, SPECIES_HUMAN_VATBORN = 20)
+ banned_job_species = list(SPECIES_PROMETHEAN, SPECIES_ZADDAT, "digital", SPECIES_DIONA)
outfit_type = /decl/hierarchy/outfit/job/hop
job_description = "The Head of Personnel manages the Service department, the Exploration team, and most other civilians. They also \
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index d08ba39915..10e231f10b 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -99,6 +99,7 @@
economic_modifier = 5
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
minimal_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
+ banned_job_species = list("digital", SPECIES_PROMETHEAN)
ideal_character_age = 40
@@ -231,6 +232,7 @@
access = list(access_lawyer, access_sec_doors, access_maint_tunnels, access_heads)
minimal_access = list(access_lawyer, access_sec_doors, access_heads)
minimal_player_age = 7
+ banned_job_species = list(SPECIES_PROMETHEAN, SPECIES_UNATHI, SPECIES_DIONA, SPECIES_TESHARI, SPECIES_ZADDAT, "digital")
outfit_type = /decl/hierarchy/outfit/job/internal_affairs_agent
job_description = "An Internal Affairs Agent makes sure that the crew is following Standard Operating Procedure. They also \
diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm
index 06ee1c6fc9..d1f5deae4c 100644
--- a/code/game/jobs/job/engineering.dm
+++ b/code/game/jobs/job/engineering.dm
@@ -17,8 +17,10 @@
economic_modifier = 10
minimum_character_age = 25
- min_age_by_species = list(SPECIES_UNATHI = 70, SPECIES_TESHARI = 20, "mechanical" = 10)
-/// ideal_character_age = 50
+ min_age_by_species = list(SPECIES_UNATHI = 70, "mechanical" = 10, SPECIES_HUMAN_VATBORN = 12)
+ ideal_character_age = 50
+ ideal_age_by_species = list(SPECIES_UNATHI = 140, "mechanical" = 20, SPECIES_HUMAN_VATBORN = 20)
+ banned_job_species = list(SPECIES_TESHARI, SPECIES_DIONA, SPECIES_PROMETHEAN, SPECIES_ZADDAT, "digital")
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index b812c4b39c..007dcad8da 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -24,6 +24,8 @@
var/minimum_character_age = 0
var/list/min_age_by_species = null
var/ideal_character_age = 30
+ var/list/ideal_age_by_species = null
+ var/list/banned_job_species = null
var/has_headset = TRUE //Do people with this job need to be given headsets and told how to use them? E.g. Cyborgs don't.
var/account_allowed = 1 // Does this job type come with a station account?
@@ -164,4 +166,15 @@
///Assigns minimum age by race & brain type. Code says Positronic = mechanical and Drone = digital because nothing can be simple.
///Will first check based on brain type, then based on species.
/datum/job/proc/get_min_age(species_name, brain_type)
- return (brain_type && LAZYACCESS(min_age_by_species, brain_type)) || LAZYACCESS(min_age_by_species, species_name) || minimum_character_age
\ No newline at end of file
+ return (brain_type && LAZYACCESS(min_age_by_species, brain_type)) || LAZYACCESS(min_age_by_species, species_name) || minimum_character_age
+
+/datum/job/proc/get_ideal_age(species_name, brain_type)
+ return (brain_type && LAZYACCESS(ideal_age_by_species, brain_type)) || LAZYACCESS(ideal_age_by_species, brain_type) || ideal_character_age
+
+/datum/job/proc/is_species_banned(species_name, brain_type)
+ if(banned_job_species == null)
+ return
+ if(species_name in banned_job_species)
+ return TRUE
+ if(brain_type in banned_job_species)
+ return TRUE
\ No newline at end of file
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index b91b546e61..eac19f5cee 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -23,9 +23,11 @@
access_keycard_auth, access_sec_doors, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
minimum_character_age = 25
- min_age_by_species = list(SPECIES_UNATHI = 70, SPECIES_TESHARI = 20, "mechanical" = 10)
+ min_age_by_species = list(SPECIES_UNATHI = 70, "mechanical" = 10, SPECIES_HUMAN_VATBORN = 12)
minimal_player_age = 10
-// ideal_character_age = 50
+ ideal_character_age = 50
+ ideal_age_by_species = list(SPECIES_UNATHI = 140, "mechanical" = 20, SPECIES_HUMAN_VATBORN = 20)
+ banned_job_species = list(SPECIES_TESHARI, SPECIES_DIONA, SPECIES_PROMETHEAN, SPECIES_ZADDAT, "digital")
outfit_type = /decl/hierarchy/outfit/job/medical/cmo
job_description = "The CMO manages the Medical department and is a position requiring experience and skill; their goal is to ensure that their \
@@ -163,6 +165,7 @@
job_description = "A Psychiatrist provides mental health services to crew members in need. They may also be called upon to determine whatever \
ails the mentally unwell, frequently under Security supervision. They understand the effects of various psychoactive drugs."
alt_titles = list("Psychologist" = /datum/alt_title/psychologist)
+ banned_job_species = list(SPECIES_PROMETHEAN, SPECIES_DIONA)
//Psychiatrist Alt Titles
/datum/alt_title/psychologist
@@ -191,6 +194,7 @@
job_description = "A Paramedic is primarily concerned with the recovery of patients who are unable to make it to the Medical Department on their own. \
They may also be called upon to keep patients stable when Medical is busy or understaffed."
alt_titles = list("Emergency Medical Technician" = /datum/alt_title/emt)
+ banned_job_species = list(SPECIES_DIONA)
minimum_character_age = 1
min_age_by_species = list(SPECIES_PROMETHEAN = 2)
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index b861c28984..b1b3a2558c 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -26,8 +26,10 @@
minimum_character_age = 25
minimal_player_age = 14
- min_age_by_species = list(SPECIES_UNATHI = 70, SPECIES_TESHARI = 20, "mechanical" = 10)
-/// ideal_character_age = 50
+ min_age_by_species = list(SPECIES_UNATHI = 70, "mechanical" = 10, SPECIES_HUMAN_VATBORN = 12)
+ ideal_character_age = 50
+ ideal_age_by_species = list(SPECIES_UNATHI = 140, "mechanical" = 20, SPECIES_HUMAN_VATBORN = 20)
+ banned_job_species = list(SPECIES_TESHARI, SPECIES_DIONA, SPECIES_PROMETHEAN, SPECIES_ZADDAT, "digital")
outfit_type = /decl/hierarchy/outfit/job/science/rd
job_description = "The Research Director manages and maintains the Research department. They are required to ensure the safety of the entire crew, \
@@ -57,6 +59,8 @@
economic_modifier = 7
access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch)
minimal_access = list(access_tox, access_tox_storage, access_research, access_xenoarch)
+ min_age_by_species = list(SPECIES_PROMETHEAN = 2)
+ banned_job_species = list("digital")
minimal_player_age = 14
@@ -100,6 +104,7 @@
economic_modifier = 7
access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_hydroponics)
minimal_access = list(access_research, access_xenobiology, access_hydroponics, access_tox_storage)
+ banned_job_species = list("digital")
minimal_player_age = 14
minimum_character_age = 1
@@ -135,6 +140,7 @@
minimal_player_age = 7
minimum_character_age = 1
min_age_by_species = list(SPECIES_PROMETHEAN = 2)
+ banned_job_species = list("digital")
outfit_type = /decl/hierarchy/outfit/job/science/roboticist
job_description = "A Roboticist maintains and repairs the station's synthetics, including crew with prosthetic limbs. \
diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm
index a639c49283..6cab6a65f1 100644
--- a/code/game/jobs/job/security.dm
+++ b/code/game/jobs/job/security.dm
@@ -24,8 +24,11 @@
access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks)
minimum_character_age = 25
- min_age_by_species = list(SPECIES_UNATHI = 70, SPECIES_TESHARI = 20, "mechanical" = 10)
+ min_age_by_species = list(SPECIES_HUMAN_VATBORN = 12)
minimal_player_age = 14
+ ideal_character_age = 50
+ ideal_age_by_species = list(SPECIES_HUMAN_VATBORN = 20)
+ banned_job_species = list(SPECIES_TESHARI, SPECIES_DIONA, SPECIES_PROMETHEAN, SPECIES_ZADDAT, "digital", SPECIES_UNATHI, "mechanical")
outfit_type = /decl/hierarchy/outfit/job/security/hos
job_description = " The Head of Security manages the Security Department, keeping the station safe and making sure the rules are followed. They are expected to \
@@ -59,6 +62,7 @@
access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_maint_tunnels, access_morgue, access_external_airlocks)
minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_maint_tunnels, access_external_airlocks)
minimal_player_age = 5
+ banned_job_species = list(SPECIES_ZADDAT, SPECIES_PROMETHEAN, SPECIES_TESHARI, SPECIES_DIONA)
outfit_type = /decl/hierarchy/outfit/job/security/warden
job_description = "The Warden watches over the physical Security Department, making sure the Brig and Armoury are secure and in order at all times. They oversee \
@@ -83,6 +87,7 @@
minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks)
economic_modifier = 5
minimal_player_age = 3
+ banned_job_species = list(SPECIES_ZADDAT, SPECIES_PROMETHEAN, SPECIES_DIONA)
outfit_type = /decl/hierarchy/outfit/job/security/detective
job_description = "A Detective works to help Security find criminals who have not properly been identified, through interviews and forensic work. \
@@ -112,6 +117,7 @@
access = list(access_security, access_eva, access_sec_doors, access_brig, access_maint_tunnels, access_morgue, access_external_airlocks)
minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_maint_tunnels, access_external_airlocks)
minimal_player_age = 3
+ banned_job_species = list(SPECIES_ZADDAT, SPECIES_TESHARI, SPECIES_DIONA)
outfit_type = /decl/hierarchy/outfit/job/security/officer
job_description = "A Security Officer is concerned with maintaining the safety and security of the station as a whole, dealing with external threats and \
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 893dbc9604..146ecf5a2e 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -91,9 +91,12 @@ var/global/datum/controller/occupations/job_master
if(!job.player_old_enough(player.client))
Debug("FOC player not old enough, Player: [player]")
continue
- if(job.minimum_character_age && (player.client.prefs.age < job.minimum_character_age))
+ if(job.minimum_character_age && (player.client.prefs.age < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data["brain"])))
Debug("FOC character not old enough, Player: [player]")
continue
+ if(job.is_species_banned(player.client.prefs.species, player.client.prefs.organ_data["brain"]) == TRUE)
+ Debug("FOC character species invalid for job, Player: [player]")
+ continue
if(flag && !(player.client.prefs.be_special & flag))
Debug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
@@ -108,7 +111,10 @@ var/global/datum/controller/occupations/job_master
if(!job)
continue
- if(job.minimum_character_age && (player.client.prefs.age < job.minimum_character_age))
+ if(job.minimum_character_age && (player.client.prefs.age < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data["brain"])))
+ continue
+
+ if(job.is_species_banned(player.client.prefs.species, player.client.prefs.organ_data["brain"]) == TRUE)
continue
if(istype(job, GetJob("Assistant"))) // We don't want to give him assistant, that's boring!
@@ -157,20 +163,18 @@ var/global/datum/controller/occupations/job_master
if(!V.client) continue
var/age = V.client.prefs.age
- if(age < job.minimum_character_age) // Nope.
+ if(age < job.get_min_age(V.client.prefs.species, V.client.prefs.organ_data["brain"])) // Nope.
continue
- switch(age)
- if(job.minimum_character_age to (job.minimum_character_age+10))
- weightedCandidates[V] = 3 // Still a bit young.
- if((job.minimum_character_age+10) to (job.ideal_character_age-10))
- weightedCandidates[V] = 6 // Better.
- if((job.ideal_character_age-10) to (job.ideal_character_age+10))
- weightedCandidates[V] = 10 // Great.
- if((job.ideal_character_age+10) to (job.ideal_character_age+20))
- weightedCandidates[V] = 6 // Still good.
- if((job.ideal_character_age+20) to INFINITY)
- weightedCandidates[V] = 3 // Geezer.
+ var/idealage = job.get_ideal_age(V.client.prefs.species, V.client.prefs.organ_data["brain"])
+ var/agediff = abs(idealage - age) // Compute the absolute difference in age from target
+ switch(agediff) /// If the math sucks, it's because I almost failed algebra in high school.
+ if(20 to INFINITY)
+ weightedCandidates[V] = 3 // Too far off
+ if(10 to 20)
+ weightedCandidates[V] = 6 // Nearer the mark, but not quite
+ if(0 to 10)
+ weightedCandidates[V] = 10 // On the mark
else
// If there's ABSOLUTELY NOBODY ELSE
if(candidates.len == 1) weightedCandidates[V] = 1
diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm
index 9d5d14ddb8..95e0d02524 100644
--- a/code/modules/client/preference_setup/occupation/occupation.dm
+++ b/code/modules/client/preference_setup/occupation/occupation.dm
@@ -123,8 +123,11 @@
var/available_in_days = job.available_in_days(user.client)
. += "[rank]