diff --git a/code/controllers/configuration_vr.dm b/code/controllers/configuration_vr.dm
index ad839a5730..a91c04e517 100644
--- a/code/controllers/configuration_vr.dm
+++ b/code/controllers/configuration_vr.dm
@@ -11,6 +11,7 @@
var/static/pto_cap = 100 //Hours
var/static/require_flavor = FALSE
var/static/ipqualityscore_apikey //API key for ipqualityscore.com
+ var/static/use_playtime_restriction_for_jobs = FALSE
/hook/startup/proc/read_vs_config()
var/list/Lines = file2list("config/config.txt")
@@ -61,4 +62,6 @@
config.require_flavor = TRUE
if ("ipqualityscore_apikey")
config.ipqualityscore_apikey = value
+ if ("use_playtime_restriction_for_jobs")
+ config.use_playtime_restriction_for_jobs = TRUE
return 1
diff --git a/code/controllers/subsystems/persist_vr.dm b/code/controllers/subsystems/persist_vr.dm
index 41811a2a6a..ca0feb37f6 100644
--- a/code/controllers/subsystems/persist_vr.dm
+++ b/code/controllers/subsystems/persist_vr.dm
@@ -47,23 +47,33 @@ SUBSYSTEM_DEF(persist)
// Update client whatever
var/client/C = M.client
- var/wait_in_hours = (wait / (1 HOUR)) * J.timeoff_factor
+ var/wait_in_hours = wait / (1 HOUR)
+ var/pto_factored = wait_in_hours * J.timeoff_factor
LAZYINITLIST(C.department_hours)
+ LAZYINITLIST(C.play_hours)
var/dept_hours = C.department_hours
- if(isnum(C.department_hours[department_earning]))
- dept_hours[department_earning] += wait_in_hours
+ var/play_hours = C.play_hours
+ if(isnum(dept_hours[department_earning]))
+ dept_hours[department_earning] += pto_factored
else
- dept_hours[department_earning] = wait_in_hours
+ dept_hours[department_earning] = pto_factored
- //Cap it
+ // If they're earning PTO they must be in a useful job so are earning playtime in that department
+ if(J.timeoff_factor > 0)
+ if(isnum(play_hours[department_earning]))
+ play_hours[department_earning] += wait_in_hours
+ else
+ play_hours[department_earning] = wait_in_hours
+
+ // Cap it
dept_hours[department_earning] = min(config.pto_cap, dept_hours[department_earning])
-
// Okay we figured it out, lets update database!
var/sql_ckey = sql_sanitize_text(C.ckey)
var/sql_dpt = sql_sanitize_text(department_earning)
var/sql_bal = text2num("[C.department_hours[department_earning]]")
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO vr_player_hours (ckey, department, hours) VALUES ('[sql_ckey]', '[sql_dpt]', [sql_bal]) ON DUPLICATE KEY UPDATE hours = VALUES(hours)")
+ var/sql_total = text2num("[C.play_hours[department_earning]]")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO vr_player_hours (ckey, department, hours, total_hours) VALUES ('[sql_ckey]', '[sql_dpt]', [sql_bal], [sql_total]) ON DUPLICATE KEY UPDATE hours = VALUES(hours), total_hours = VALUES(total_hours)")
query.Execute()
if (MC_TICK_CHECK)
diff --git a/code/game/jobs/job/captain_vr.dm b/code/game/jobs/job/captain_vr.dm
index f08a1b4079..746d92cf86 100644
--- a/code/game/jobs/job/captain_vr.dm
+++ b/code/game/jobs/job/captain_vr.dm
@@ -1,12 +1,14 @@
/datum/job/captain
disallow_jobhop = TRUE
pto_type = PTO_CIVILIAN
+ //dept_time_required = 60 //Pending something more complicated
/datum/job/hop
disallow_jobhop = TRUE
pto_type = PTO_CIVILIAN
departments = list(DEPARTMENT_COMMAND, DEPARTMENT_CIVILIAN)
departments_managed = list(DEPARTMENT_CIVILIAN, DEPARTMENT_CARGO, DEPARTMENT_PLANET)
+ dept_time_required = 60
alt_titles = list("Crew Resources Officer" = /datum/alt_title/cro,
"Deputy Director" = /datum/alt_title/deputy_director)
diff --git a/code/game/jobs/job/civilian_vr.dm b/code/game/jobs/job/civilian_vr.dm
index 2844108187..433935e55b 100644
--- a/code/game/jobs/job/civilian_vr.dm
+++ b/code/game/jobs/job/civilian_vr.dm
@@ -12,6 +12,7 @@
/datum/job/qm
pto_type = PTO_CARGO
+ dept_time_required = 20
/datum/job/cargo_tech
total_positions = 3
diff --git a/code/game/jobs/job/engineering_vr.dm b/code/game/jobs/job/engineering_vr.dm
index 10337d9881..0ed001bd28 100644
--- a/code/game/jobs/job/engineering_vr.dm
+++ b/code/game/jobs/job/engineering_vr.dm
@@ -1,6 +1,7 @@
/datum/job/chief_engineer
disallow_jobhop = TRUE
pto_type = PTO_ENGINEERING
+ dept_time_required = 60
/datum/job/engineer
pto_type = PTO_ENGINEERING
diff --git a/code/game/jobs/job/exploration_vr.dm b/code/game/jobs/job/exploration_vr.dm
index 987041de61..d555c531a2 100644
--- a/code/game/jobs/job/exploration_vr.dm
+++ b/code/game/jobs/job/exploration_vr.dm
@@ -44,6 +44,7 @@ var/const/SAR =(1<<14)
economic_modifier = 8
minimal_player_age = 7
pto_type = PTO_EXPLORATION
+ dept_time_required = 20
access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_gateway)
minimal_access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_gateway)
diff --git a/code/game/jobs/job/job_vr.dm b/code/game/jobs/job/job_vr.dm
index ce982aaab9..05874df0d1 100644
--- a/code/game/jobs/job/job_vr.dm
+++ b/code/game/jobs/job/job_vr.dm
@@ -14,6 +14,17 @@
//Disallow joining as this job midround from off-duty position via going on-duty
var/disallow_jobhop = FALSE
+ //Time required in the department as other jobs before playing this one (in hours)
+ var/dept_time_required = 0
+
// Check client-specific availability rules.
/datum/job/proc/player_has_enough_pto(client/C)
return timeoff_factor >= 0 || (C && LAZYACCESS(C.department_hours, pto_type) > 0)
+
+/datum/job/proc/player_has_enough_playtime(client/C)
+ return (available_in_playhours(C) == 0)
+
+/datum/job/proc/available_in_playhours(client/C)
+ if(C && config.use_playtime_restriction_for_jobs && isnum(C.play_hours[pto_type]) && dept_time_required > 0)
+ return max(0, dept_time_required - C.play_hours[pto_type])
+ return 0
\ No newline at end of file
diff --git a/code/game/jobs/job/medical_vr.dm b/code/game/jobs/job/medical_vr.dm
index 306fe9acaa..1a29d1ec9d 100644
--- a/code/game/jobs/job/medical_vr.dm
+++ b/code/game/jobs/job/medical_vr.dm
@@ -1,6 +1,7 @@
/datum/job/cmo
disallow_jobhop = TRUE
pto_type = PTO_MEDICAL
+ dept_time_required = 60
/datum/job/doctor
spawn_positions = 5
diff --git a/code/game/jobs/job/science_vr.dm b/code/game/jobs/job/science_vr.dm
index 367eb5dd8a..679fbcbc83 100644
--- a/code/game/jobs/job/science_vr.dm
+++ b/code/game/jobs/job/science_vr.dm
@@ -1,6 +1,7 @@
/datum/job/rd
disallow_jobhop = TRUE
pto_type = PTO_SCIENCE
+ dept_time_required = 60
access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
access_tox_storage, access_teleporter, access_sec_doors,
diff --git a/code/game/jobs/job/security_vr.dm b/code/game/jobs/job/security_vr.dm
index 9e55d807b0..24b4a33325 100644
--- a/code/game/jobs/job/security_vr.dm
+++ b/code/game/jobs/job/security_vr.dm
@@ -1,6 +1,7 @@
/datum/job/hos
disallow_jobhop = TRUE
pto_type = PTO_SECURITY
+ dept_time_required = 60
access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
@@ -13,6 +14,7 @@
/datum/job/warden
pto_type = PTO_SECURITY
+ dept_time_required = 20
/datum/job/detective
pto_type = PTO_SECURITY
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 600abd899c..2470fdc114 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -60,8 +60,12 @@ var/global/datum/controller/occupations/job_master
return 0
if(!job.player_old_enough(player.client))
return 0
- if(!is_job_whitelisted(player, rank)) //VOREStation Code
+ //VOREStation Add
+ if(!job.player_has_enough_playtime(player.client))
return 0
+ if(!is_job_whitelisted(player, rank))
+ return 0
+ //VOREStation Add End
var/position_limit = job.total_positions
if(!latejoin)
@@ -97,6 +101,9 @@ var/global/datum/controller/occupations/job_master
Debug("FOC character not old enough, Player: [player]")
continue
//VOREStation Code Start
+ if(!job.player_has_enough_playtime(player.client))
+ Debug("FOC character not enough playtime, Player: [player]")
+ continue
if(!is_job_whitelisted(player, job.title))
Debug("FOC is_job_whitelisted failed, Player: [player]")
continue
@@ -133,6 +140,9 @@ var/global/datum/controller/occupations/job_master
continue
//VOREStation Code Start
+ if(!job.player_has_enough_playtime(player.client))
+ Debug("GRJ player not enough playtime, Player: [player]")
+ continue
if(!is_job_whitelisted(player, job.title))
Debug("GRJ player not whitelisted for this job, Player: [player], Job: [job.title]")
continue
@@ -283,6 +293,12 @@ var/global/datum/controller/occupations/job_master
Debug("DO player not old enough, Player: [player], Job:[job.title]")
continue
+ //VOREStation Add
+ if(!job.player_has_enough_playtime(player.client))
+ Debug("DO player not enough playtime, Player: [player]")
+ continue
+ //VOREStation Add End
+
// If the player wants that job on this level, then try give it to him.
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
@@ -610,6 +626,11 @@ var/global/datum/controller/occupations/job_master
if(!job.player_old_enough(player.client))
level6++
continue
+ //VOREStation Add
+ if(!job.player_has_enough_playtime(player.client))
+ level6++
+ continue
+ //VOREStation Add End
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
level1++
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm
index 42e78683ec..85924d79f6 100644
--- a/code/game/machinery/computer/timeclock_vr.dm
+++ b/code/game/machinery/computer/timeclock_vr.dm
@@ -154,6 +154,7 @@
&& !job.whitelist_only \
&& !jobban_isbanned(user,job.title) \
&& job.player_old_enough(user.client) \
+ && job.player_has_enough_playtime(user.client) \
&& job.pto_type == department \
&& !job.disallow_jobhop \
&& job.timeoff_factor > 0
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index 99d975c454..0a0810a54a 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -54,6 +54,7 @@
var/account_join_date = "(Requires database)"
var/account_age = "(Requires database)"
var/list/department_hours // VOREStation Edit - Track hours of leave accured for each department.
+ var/list/play_hours // VOREStation Edit - Tracks total playtime hours for each departments.
preload_rsc = PRELOAD_RSC
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index f8ab8ec8e9..dd36a877e2 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -324,11 +324,13 @@
// VOREStation Edit Start - Department Hours
if(config.time_off)
- var/DBQuery/query_hours = dbcon.NewQuery("SELECT department, hours FROM vr_player_hours WHERE ckey = '[sql_ckey]'")
+ var/DBQuery/query_hours = dbcon.NewQuery("SELECT department, hours, total_hours FROM vr_player_hours WHERE ckey = '[sql_ckey]'")
query_hours.Execute()
+ LAZYINITLIST(department_hours)
+ LAZYINITLIST(play_hours)
while(query_hours.NextRow())
- LAZYINITLIST(department_hours)
department_hours[query_hours.item[1]] = text2num(query_hours.item[2])
+ play_hours[query_hours.item[1]] = text2num(query_hours.item[3])
// VOREStation Edit End - Department Hours
if(sql_id)
diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm
index 9ab76b9f4e..42794aa8bf 100644
--- a/code/modules/client/preference_setup/occupation/occupation.dm
+++ b/code/modules/client/preference_setup/occupation/occupation.dm
@@ -143,6 +143,12 @@
var/available_in_days = job.available_in_days(user.client)
. += "[rank]