Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timelock System to all Jobs, Revival PR. #692

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 133 additions & 2 deletions code/__DEFINES/jobs.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define get_job_playtime(client, job) ((client.prefs.exp[job]) ? client.prefs.exp[job] MINUTES_TO_DECISECOND : 0)

#define JOB_AVAILABLE 0
#define JOB_UNAVAILABLE_GENERIC 1
Expand All @@ -11,10 +12,13 @@
#define JOB_UNAVAILABLE_SPECIES_LIMITED 9
#define JOB_UNAVAILABLE_CLAN 10
#define JOB_UNAVAILABLE_AGE 11
#define JOB_UNAVAILABE_TIME_LOCK 12

#define DEFAULT_RELIGION "Christianity"
#define DEFAULT_DEITY "Space Jesus"

// Job Display on preference

#define JOB_DISPLAY_ORDER_DEFAULT 0

#define JOB_DISPLAY_ORDER_CITIZEN 1
Expand Down Expand Up @@ -45,13 +49,140 @@
#define JOB_DISPLAY_ORDER_ARCHIVIST 26
#define JOB_DISPLAY_ORDER_GIOVANNI 27
#define JOB_DISPLAY_ORDER_POLICE_CHIEF 28
#define JOB_DISPLAY_ORDER_POLICE 29
#define JOB_DISPLAY_ORDER_POLICE_SERGEANT 30
#define JOB_DISPLAY_ORDER_POLICE_SERGEANT 29
#define JOB_DISPLAY_ORDER_POLICE 30
#define JOB_DISPLAY_ORDER_FBI 31
#define JOB_DISPLAY_ORDER_VOIVODE 32
#define JOB_DISPLAY_ORDER_BOGATYR 33
#define JOB_DISPLAY_ORDER_ZADRUGA 34

// Job Titles
#define JOB_LIVING_ROLES /datum/timelock/living

#define JOB_CIVILIAN "Citizen"

#define JOB_UNALIGNED_ROLES /datum/timelock/unaligned
#define JOB_UNALIGNED_ROLES_LIST list(JOB_CIVILIAN)

#define JOB_PRINCE "Prince"
#define JOB_CLERK "Seneschal"
#define JOB_SHERIFF "Sheriff"
#define JOB_HOUND "Hound"

#define JOB_CAMARILLA_AUTHORITIES_ROLES /datum/timelock/camarilla_authorities
#define JOB_CAMARILLA_AUTHORITIES_ROLES_LIST list(JOB_SHERIFF, JOB_HOUND, JOB_CLERK, JOB_PRINCE)


#define JOB_BRUJAH "Primogen Brujah"
#define JOB_MALKAVIAN "Primogen Malkavian"
#define JOB_NOSFERATU "Primogen Nosferatu"
#define JOB_TOREADOR "Primogen Toreador"
#define JOB_VENTRUE "Primogen Ventrue"

#define JOB_CAMARILLA_COUNCIL_ROLES /datum/timelock/camarilla_council
#define JOB_CAMARILLA_COUNCIL_ROLES_LIST list(JOB_BRUJAH, JOB_MALKAVIAN,JOB_NOSFERATU, JOB_TOREADOR, JOB_VENTRUE)


#define JOB_PRIEST "Priest"

#define JOB_CHURCH_ROLES /datum/timelock/church
#define JOB_CHURCH_ROLES_LIST list(JOB_PRIEST)


#define JOB_GRAVEYARD "Graveyard Keeper"
#define JOB_STREETJAN "Street Janitor"
#define JOB_STRIP "Stripper"
#define JOB_TAXI "Taxi Driver"


#define JOB_CITY_SERVICES_ROLES /datum/timelock/city_services
#define JOB_CITY_SERVICES_ROLES_LIST list(JOB_GRAVEYARD,JOB_STREETJAN, JOB_STRIP, JOB_TAXI)


#define JOB_CLINIC_DIRECTOR "Clinic Director"
#define JOB_DOCTOR "Doctor"


#define JOB_CLINIC_ROLES /datum/timelock/clinic
#define JOB_CLINIC_ROLES_LIST list(JOB_CLINIC_DIRECTOR,JOB_DOCTOR)


#define JOB_TRIAD_GANGSTER "Triad Soldier"

#define JOB_GANG_ROLES /datum/timelock/gang
#define JOB_GANG_ROLES_LIST list(JOB_TRIAD_GANGSTER)

#define JOB_BARKEEPER "Baron"
#define JOB_EMISSARY "Emissary"
#define JOB_BRUISER "Bruiser"
#define JOB_SWEEPER "Sweeper"


#define JOB_ANARCH_ROLES /datum/timelock/anarch
#define JOB_ANARCH_ROLES_LIST list(JOB_BARKEEPER,JOB_EMISSARY,JOB_BRUISER,JOB_SWEEPER)

#define JOB_DEALER "Dealer"
#define JOB_SUPPLY "Supply Technician"

#define JOB_WAREHOUSE_ROLES /datum/timelock/warehouse
#define JOB_WAREHOUSE_ROLES_LIST list(JOB_DEALER,JOB_SUPPLY)

#define JOB_REGENT "Chantry Regent"
#define JOB_ARCHIVIST "Chantry Archivist"

#define JOB_TREMERE_ROLES /datum/timelock/tremere
#define JOB_TREMERE_ROLES_LIST list(JOB_REGENT,JOB_ARCHIVIST)

#define JOB_GIOVANNI_CAPO "Capo"
#define JOB_GIOVANNI_SQUADRA "La Squadra"
#define JOB_GIOVANNI_FAMIGLIA "La Famiglia"

#define JOB_GIOVANNI_ROLES /datum/timelock/giovanni_family
#define JOB_GIOVANNI_ROLES_LIST list(JOB_GIOVANNI_CAPO,JOB_GIOVANNI_SQUADRA,JOB_GIOVANNI_FAMIGLIA)

#define JOB_POLICE_CHIEF "Police Chief"
#define JOB_POLICE_SERGEANT "Police Sergeant"
#define JOB_POLICE "Police Officer"

#define JOB_POLICE_ROLES /datum/timelock/police_force
#define JOB_POLICE_ROLES_LIST list(JOB_POLICE_CHIEF,JOB_POLICE_SERGEANT,JOB_POLICE)

#define JOB_FBI "Federal Investigator"

#define JOB_NATIONAL_SECURITY_ROLES /datum/timelock/national_security
#define JOB_NATIONAL_SECURITY_ROLES_LIST list(JOB_FBI)

#define JOB_VOIVODE "Voivode"
#define JOB_BOGATYR "Bogatyr"
#define JOB_ZADRUGA "Zadruga"

#define JOB_TZIMISCE_MANSION_ROLES /datum/timelock/tzimisce_mansion_v
#define JOB_TZIMISCE_MANSION_ROLES_LIST list(JOB_VOIVODE,JOB_BOGATYR,JOB_ZADRUGA)



#define TIMELOCK_JOB(role_id, hours) new/datum/timelock(role_id, hours, role_id)



// Used to add a timelock to a job. Will be passed onto derivatives
#define AddTimelock(Path, timelockList) \
##Path/setup_requirements(list/L){\
L += timelockList;\
. = ..(L);\
}

// Used to add a timelock to a job. Will be passed onto derivates. Will not include the parent's timelocks.
#define OverrideTimelock(Path, timelockList) \
##Path/setup_requirements(list/L){\
L = timelockList;\
. = ..(L);\
}





// #define JOB_DISPLAY_ORDER_INVESTIGATOR 25
// #define JOB_DISPLAY_ORDER_CHAPLAIN 26
/*
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/time.dm
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using

#define HOURS MINUTES*60

#define MINUTES_TO_DECISECOND *600

#define TICKS *world.tick_lag

#define DS2TICKS(DS) ((DS)/world.tick_lag)
Expand Down
11 changes: 11 additions & 0 deletions code/__HELPERS/time.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@
else
SSticker.gametime_offset = CEILING(SSticker.gametime_offset, 3600)

/proc/deciseconds_to_time_text(deciseconds)
var/total_seconds = round(deciseconds / 10)
var/total_minutes = total_seconds / 60
var/hours = total_minutes / 60
var/minutes = total_minutes % 60

return "[round(hours)]:[minutes < 10 ? "0[minutes]" : minutes] Hours"

/proc/duration2text_custom(deciseconds)
return deciseconds_to_time_text(deciseconds)

//returns timestamp in a sql and a not-quite-compliant ISO 8601 friendly format
/proc/SQLtime(timevar)
return time2text(timevar || world.timeofday, "YYYY-MM-DD hh:mm:ss")
Expand Down
18 changes: 7 additions & 11 deletions code/controllers/subsystem/job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ SUBSYSTEM_DEF(job)
return FALSE
if(!job.player_old_enough(player.client) && !bypass)
return FALSE
if(job.required_playtime_remaining(player.client) && !bypass)
if(job.can_play_role(player.client) && !bypass)
return FALSE
if((player.client.prefs.generation > job.minimal_generation) && !bypass)
return FALSE
Expand Down Expand Up @@ -136,9 +136,8 @@ SUBSYSTEM_DEF(job)
if(!job.player_old_enough(player.client) && !bypass)
JobDebug("FOC player not old enough, Player: [player]")
continue
if(job.required_playtime_remaining(player.client) && !bypass)
JobDebug("FOC player not enough xp, Player: [player]")
continue
if(!job.can_play_role(player.client) && !bypass)
JobDebug("FOC player don't got enough hours(TIMELOCK), Player: [player], Job:[job.title]")
if((player.client.prefs.generation > job.minimal_generation) && !bypass)
JobDebug("FOC player not enough generation, Player: [player]")
continue
Expand Down Expand Up @@ -195,9 +194,8 @@ SUBSYSTEM_DEF(job)
JobDebug("GRJ player not old enough, Player: [player]")
continue

if(job.required_playtime_remaining(player.client))
JobDebug("GRJ player not enough xp, Player: [player]")
continue
if(!job.can_play_role(player.client))
JobDebug("GRJ player not enough playtime (TIMELOCK), Player: [player], Job:[job.title]")

if(player.client.prefs.generation > job.minimal_generation)
JobDebug("GRJ player not enough generation, Player: [player]")
Expand Down Expand Up @@ -405,10 +403,8 @@ SUBSYSTEM_DEF(job)
JobDebug("DO player not old enough, Player: [player], Job:[job.title]")
continue

if(job.required_playtime_remaining(player.client) && !bypass)
JobDebug("DO player not enough xp, Player: [player], Job:[job.title]")
continue

if(!job.can_play_role(player.client) && !bypass)
JobDebug("DO player not enough playtime (TIMELOCK), Player: [player], Job:[job.title]")
if((player.client.prefs.generation > job.minimal_generation) && !bypass)
JobDebug("DO player not enough generation, Player: [player]")
continue
Expand Down
32 changes: 20 additions & 12 deletions code/modules/client/preferences.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
popup.open(FALSE)
onclose(user, "capturekeypress", src)

/datum/preferences/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620)
/datum/preferences/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 400, height = 700)
if(!SSjob)
return

Expand Down Expand Up @@ -1349,21 +1349,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(is_banned_from(user.ckey, rank))
HTML += "<font color=red>[rank]</font></td><td><a href='?_src_=prefs;bancheck=[rank]'> BANNED</a></td></tr>"
continue
var/required_playtime_remaining = job.required_playtime_remaining(user.client)
//<font color=red>text</font> (Zamenil potomu chto slishkom rezhet glaza
if(required_playtime_remaining && !bypass)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[ [get_exp_format(required_playtime_remaining)] as [job.get_exp_req_type()] \]</font></td></tr>"
continue
if(!job.player_old_enough(user.client) && !bypass)
var/available_in_days = job.available_in_days(user.client)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[IN [(available_in_days)] DAYS\]</font></td></tr>"
continue
if((generation > job.minimal_generation) && !bypass)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[FROM [job.minimal_generation] GENERATION AND OLDER\]</font></td></tr>"
continue
if((masquerade < job.minimal_masquerade) && !bypass)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[[job.minimal_masquerade] MASQUERADE POINTS REQUIRED\]</font></td></tr>"
continue
if(!job.allowed_species.Find(pref_species.name) && !bypass)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[[pref_species.name] RESTRICTED\]</font></td></tr>"
continue
Expand All @@ -1376,6 +1366,24 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(!alloww && !bypass)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[[clane.name] RESTRICTED\]</font></td></tr>"
continue
if((generation > job.minimal_generation) && !bypass)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[FROM [job.minimal_generation] GENERATION AND OLDER\]</font></td></tr>"
continue
if((masquerade < job.minimal_masquerade) && !bypass)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[[job.minimal_masquerade] MASQUERADE POINTS REQUIRED\]</font></td></tr>"
continue
if(!job.can_play_role(user.client) && !bypass)
var/list/missing_requirements = job.get_role_requirements(user.client)
HTML += "<font color=#290204>[rank]</font></td><td><font color=#290204> \[TIMELOCKED\]</font></td></tr>"

HTML += "<tr><td colspan='2'><table width='100%' style='border: 1px solid #ccc; margin-bottom: 3px; margin-top: 3px;'>"
for(var/r in missing_requirements)
var/datum/timelock/T = r
var/requirement_message = "Lacking : [duration2text_custom(missing_requirements[r])]"
HTML += "<tr><td style='padding: 5px;'><b>[T.name]</b></td><td align='right' style='color: gray; '>[requirement_message]</td></tr>"

HTML += "</table></td></tr>"
continue
if((job_preferences[SSjob.overflow_role] == JP_LOW) && (rank != SSjob.overflow_role) && !is_banned_from(user.ckey, SSjob.overflow_role))
HTML += "<font color=orange>[rank]</font></td><td></td></tr>"
continue
Expand All @@ -1384,7 +1392,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
HTML += "<span class='dark'>[rank]</span>"

HTML += "</td><td width='40%'>"
HTML += "</td><td width='50%'>"

var/prefLevelLabel = "ERROR"
var/prefLevelColor = "pink"
Expand Down
7 changes: 7 additions & 0 deletions code/modules/jobs/job_exp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,10 @@ GLOBAL_PROTECT(exp_to_update)
prefs.db_flags = 0 //This PROBABLY won't happen, but better safe than sorry.
qdel(flags_read)
return TRUE

//This one is used for the timelock
client/proc/get_time_living()
if(!prefs.exp || !prefs.exp[EXP_TYPE_LIVING])
return 0
var/exp_living = text2num(prefs.exp[EXP_TYPE_LIVING]) MINUTES_TO_DECISECOND
return exp_living
72 changes: 72 additions & 0 deletions code/modules/jobs/job_types/_job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,17 @@
var/duty
var/v_duty


var/list/minimum_playtimes

var/minimum_playtime_as_job = 1 HOURS

/datum/job/New()
. = ..()
var/list/jobs_changes = GetMapChanges()

minimum_playtimes = setup_requirements(list())

if(!jobs_changes)
return
if(isnum(jobs_changes["additional_access"]))
Expand Down Expand Up @@ -347,3 +355,67 @@
if(CONFIG_GET(flag/security_has_maint_access))
return list(ACCESS_MAINT_TUNNELS)
return list()

/datum/timelock
var/name
var/time_required
var/roles

/datum/timelock/New(name, time_required, list/roles)
. = ..()
if(name) src.name = name
if(time_required) src.time_required = time_required
if(roles) src.roles = roles

/datum/job/proc/setup_requirements(list/L)
var/list/to_return = list()
for(var/PT in L)
if(ispath(PT))
LAZYADD(to_return, new PT(time_required = L[PT]))
else
LAZYADD(to_return, TIMELOCK_JOB(PT, L[PT]))

return to_return

/datum/timelock/proc/can_play(client/C)
if(islist(roles))
var/total = 0
for(var/role_required in roles)
total += get_job_playtime(C, role_required)

return total >= time_required
else
return get_job_playtime(C, roles) >= time_required

/datum/timelock/proc/get_role_requirement(client/C)
if(islist(roles))
var/total = 0
for(var/role_required in roles)
total += get_job_playtime(C, role_required)

return time_required - total
else
return time_required - get_job_playtime(C, roles)

/datum/job/proc/can_play_role(client/client)


if(get_job_playtime(client, title) > minimum_playtime_as_job)
return TRUE

for(var/prereq in minimum_playtimes)
var/datum/timelock/T = prereq
if(!T.can_play(client))
return FALSE

return TRUE

/datum/job/proc/get_role_requirements(client/C)
var/list/return_requirements = list()
for(var/prereq in minimum_playtimes)
var/datum/timelock/T = prereq
var/time_required = T.get_role_requirement(C)
if(time_required > 0)
return_requirements[T] = time_required

return return_requirements
Loading