diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 5edccb012e3..2d2acdbbba5 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -454,7 +454,7 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time =
if(roletext)
if(jobban_isbanned(G, roletext) || jobban_isbanned(G, "Syndicate"))
continue
- if(min_hours)
+ if(config.use_exp_restrictions && min_hours)
if(G.client.get_exp_living_num() < min_hours * 60)
continue
if(G.has_enabled_antagHUD)
diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm
index c9ce95a86a9..4a1624426b7 100644
--- a/code/game/jobs/job_exp.dm
+++ b/code/game/jobs/job_exp.dm
@@ -1,3 +1,40 @@
+// Playtime requirements for special roles (hours)
+
+var/global/list/role_playtime_requirements = list(
+ // CREW-FRIENDLY ROLES
+ ROLE_PAI = 0,
+ ROLE_POSIBRAIN = 5, // Same as cyborg job.
+ ROLE_SENTIENT = 5,
+ ROLE_ERT = 10, // High, because they're team-based, and we want ERT to be robust
+ ROLE_TRADER = 5,
+
+ // SOLO ANTAGS
+ ROLE_TRAITOR = 3,
+ ROLE_CHANGELING = 3,
+ ROLE_WIZARD = 3,
+ ROLE_VAMPIRE = 3,
+ ROLE_BLOB = 3,
+ ROLE_REVENANT = 3,
+ ROLE_BORER = 3,
+ ROLE_NINJA = 3,
+ ROLE_MORPH = 3,
+ ROLE_DEMON = 3,
+
+ // DUO ANTAGS
+ ROLE_GUARDIAN = 5,
+ ROLE_GSPIDER = 5,
+
+ // TEAM ANTAGS
+ // Higher numbers here, because they require more experience to be played correctly
+ ROLE_SHADOWLING = 10,
+ ROLE_REV = 10,
+ ROLE_OPERATIVE = 10,
+ ROLE_CULTIST = 10,
+ ROLE_RAIDER = 10,
+ ROLE_ALIEN = 10,
+ ROLE_ABDUCTOR = 10,
+)
+
// Admin Verbs
/client/proc/cmd_mentor_check_player_exp() //Allows admins to determine who the newer players are.
@@ -53,6 +90,27 @@
// Procs
+/proc/role_available_in_playtime(client/C, role)
+ if(!C)
+ return 0
+ if(!role)
+ return 0
+ if(!config.use_exp_restrictions)
+ return 0
+ if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, C.mob))
+ return 0
+ var/list/play_records = params2list(C.prefs.exp)
+ var/isexempt = text2num(play_records[EXP_TYPE_EXEMPT])
+ if(isexempt)
+ return 0
+ var/minimal_player_hrs = role_playtime_requirements[role]
+ if(!minimal_player_hrs)
+ return 0
+ var/req_mins = minimal_player_hrs * 60
+ var/my_exp = text2num(play_records[EXP_TYPE_CREW])
+ if(!isnum(my_exp))
+ return req_mins
+ return max(0, req_mins - my_exp)
/datum/job/proc/available_in_playtime(client/C)
if(!C)
diff --git a/code/game/response_team.dm b/code/game/response_team.dm
index 5b0cec99de1..bf25ad6760e 100644
--- a/code/game/response_team.dm
+++ b/code/game/response_team.dm
@@ -104,7 +104,7 @@ var/ert_request_answered = 0
active_team = response_team_type
send_emergency_team = 1
- var/list/ert_candidates = pollCandidates("Join the Emergency Response Team?",, responseteam_age, 600, 1)
+ var/list/ert_candidates = pollCandidates("Join the Emergency Response Team?",, responseteam_age, 600, 1, role_playtime_requirements[ROLE_ERT])
if(!ert_candidates.len)
active_team.cannot_send_team()
send_emergency_team = 0
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index 4f11adc7e93..891b9d70813 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -28,9 +28,11 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
)
/proc/player_old_enough_antag(client/C, role)
- if(available_in_days_antag(C, role) == 0)
- return 1 //Available in 0 days = available right now = player is old enough to play.
- return 0
+ if(available_in_days_antag(C, role))
+ return 0 //available_in_days>0 = still some days required = player not old enough
+ if(role_available_in_playtime(C, role))
+ return 0 //available_in_playtime>0 = still some more playtime required = they are not eligible
+ return 1
/proc/available_in_days_antag(client/C, role)
if(!C)
@@ -472,9 +474,15 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
for(var/i in special_roles)
if(jobban_isbanned(user, i))
dat += "Be [capitalize(i)]: \[BANNED]
"
- else if(!player_old_enough_antag(user.client,i))
- var/available_in_days_antag = available_in_days_antag(user.client,i)
- dat += "Be [capitalize(i)]: \[IN [(available_in_days_antag)] DAYS]
"
+ else if(!player_old_enough_antag(user.client, i))
+ var/available_in_days_antag = available_in_days_antag(user.client, i)
+ var/role_available_in_playtime = get_exp_format(role_available_in_playtime(user.client, i))
+ if(available_in_days_antag)
+ dat += "Be [capitalize(i)]: \[IN [(available_in_days_antag)] DAYS]
"
+ else if(role_available_in_playtime)
+ dat += "Be [capitalize(i)]: \[IN [(role_available_in_playtime)]]
"
+ else
+ dat += "Be [capitalize(i)]: \[ERROR]
"
else
dat += "Be [capitalize(i)]: [(i in src.be_special) ? "Yes" : "No"]
"
dat += ""