Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

playtime-tgui + refactor exp gain #212

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions code/__DEFINES/_subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
#define INIT_ORDER_PATH -50
#define INIT_ORDER_EXPLOSIONS -69
#define INIT_ORDER_EXCAVATION -78
#define INIT_ORDER_EXP_TRACKER -90
#define INIT_ORDER_STATPANELS -97
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.

Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/jobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@
#define JOB_CAT_CIVILIAN "Civilian"
#define JOB_CAT_MARINE "Marine"
#define JOB_CAT_XENO "Xenomorph"
#define JOB_CAT_TGMC "TGMC"
#define JOB_CAT_SOM "SOM"
#define JOB_CAT_UNASSIGNED "Unassigned"

#define JOB_COMM_TITLE_SQUAD_LEADER "SL"
Expand Down
4 changes: 0 additions & 4 deletions code/controllers/subsystem/blackbox.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ SUBSYSTEM_DEF(blackbox)
SSdbcore.InitializeRound()


if(CONFIG_GET(flag/use_exp_tracking))
update_exp(10, FALSE)


/datum/controller/subsystem/blackbox/vv_get_var(var_name)
if(var_name == "feedback")
return debug_variable(var_name, deepCopyList(feedback), 0, src)
Expand Down
9 changes: 6 additions & 3 deletions code/controllers/subsystem/job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ SUBSYSTEM_DEF(job)
flags = SS_NO_FIRE
var/ssjob_flags = NONE

var/list/occupations = list() //List of all jobs.
var/list/all_name_occupations = list() //Dict of all jobs, keys are titles
var/list/occupations = list() //List of available jobs.
var/list/joinable_occupations = list() //List of jobs that can be joined as through the lobby.
var/list/joinable_occupations_by_category = list()
var/list/active_occupations = list() //Jobs in use by the game mode at roundstart.
var/list/active_joinable_occupations = list() //Jobs currently joineable through the lobby (roundstart-only removed after).
var/list/active_joinable_occupations_by_category = list()
var/list/datum/job/name_occupations = list() //Dict of all jobs, keys are titles.
var/list/type_occupations = list() //Dict of all jobs, keys are types.
var/list/datum/job/name_occupations = list() //Dict of available jobs, keys are titles.
var/list/type_occupations = list() //Dict of available jobs, keys are types.

var/list/squads = list() //List of potential squads.
///Assoc list of all joinable squads, categorised by faction
Expand Down Expand Up @@ -47,6 +48,8 @@ SUBSYSTEM_DEF(job)
var/datum/job/job = new J()
if(!job)
continue
all_name_occupations[job.title] = job

if(!job.config_check())
continue
if(!job.map_check())
Expand Down
18 changes: 9 additions & 9 deletions code/datums/jobs/job/fallen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,38 +31,38 @@
qdel(source)

/datum/job/fallen/marine
title = SQUAD_MARINE
title = "Fallen " + SQUAD_MARINE
outfit = /datum/outfit/job/marine/standard

/datum/job/fallen/marine/standard

/datum/job/fallen/marine/engineer
title = SQUAD_ENGINEER
title = "Fallen " + SQUAD_ENGINEER
skills_type = /datum/skills/combat_engineer
outfit = /datum/outfit/job/marine/engineer

/datum/job/fallen/marine/corpsman
title = SQUAD_CORPSMAN
title = "Fallen " + SQUAD_CORPSMAN
skills_type = /datum/skills/combat_medic
outfit = /datum/outfit/job/marine/corpsman

/datum/job/fallen/marine/smartgunner
title = SQUAD_SMARTGUNNER
title = "Fallen " + SQUAD_SMARTGUNNER
skills_type = /datum/skills/smartgunner
outfit = /datum/outfit/job/marine/smartgunner

/datum/job/fallen/marine/leader
title = SQUAD_LEADER
title = "Fallen " + SQUAD_LEADER
skills_type = /datum/skills/sl
outfit = /datum/outfit/job/marine/leader

/datum/job/fallen/marine/mechpilot
title = MECH_PILOT
title = "Fallen " + MECH_PILOT
skills_type = /datum/skills/mech_pilot
outfit = /datum/outfit/job/command/mech_pilot

/datum/job/fallen/marine/fieldcommander
title = FIELD_COMMANDER
title = "Fallen " + FIELD_COMMANDER
skills_type = /datum/skills/fo
outfit = /datum/outfit/job/command/fieldcommander
multiple_outfits = TRUE
Expand All @@ -72,7 +72,7 @@
)

/datum/job/fallen/marine/synthetic
title = SYNTHETIC
title = "Fallen " + SYNTHETIC
skills_type = /datum/skills/synthetic
outfit = /datum/outfit/job/civilian/synthetic

Expand All @@ -90,4 +90,4 @@
return ..()

/datum/job/fallen/xenomorph
title = ROLE_XENOMORPH
title = "Fallen " + ROLE_XENOMORPH
1 change: 0 additions & 1 deletion code/datums/jobs/job/freelancers.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/datum/job/freelancer
job_category = JOB_CAT_MARINE
access = ALL_ANTAGONIST_ACCESS
minimal_access = ALL_ANTAGONIST_ACCESS
skills_type = /datum/skills/crafty
Expand Down
1 change: 0 additions & 1 deletion code/datums/jobs/job/icc.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/datum/job/icc
job_category = JOB_CAT_MARINE
access = ALL_ANTAGONIST_ACCESS
minimal_access = ALL_ANTAGONIST_ACCESS
skills_type = /datum/skills/craftier
Expand Down
1 change: 0 additions & 1 deletion code/datums/jobs/job/imperium.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/datum/job/imperial
job_category = JOB_CAT_MARINE
comm_title = "IMP"
faction = FACTION_IMP
skills_type = /datum/skills/imperial
Expand Down
234 changes: 9 additions & 225 deletions code/datums/jobs/job/job_exp.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
GLOBAL_LIST_EMPTY(exp_to_update)
GLOBAL_PROTECT(exp_to_update)


/datum/job/proc/required_playtime_remaining(client/C)
if(!C)
return FALSE
Expand All @@ -11,11 +7,11 @@ GLOBAL_PROTECT(exp_to_update)
return FALSE
if(!exp_requirements || !exp_type)
return FALSE
if(!job_is_xp_locked(src))
if(!job_is_xp_locked())
return FALSE
if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_other_rights(C, R_ADMIN, FALSE))
return FALSE
var/my_exp = C.calc_exp_type(get_exp_req_type())
var/my_exp = C.get_exp_job(get_exp_req_type())
var/job_requirement = get_exp_req_amount()
if(my_exp >= job_requirement)
return FALSE
Expand All @@ -38,227 +34,15 @@ GLOBAL_PROTECT(exp_to_update)
return exp_type


/proc/job_is_xp_locked(datum/job/job)
if(!CONFIG_GET(flag/use_exp_restrictions_command) && job.job_flags & JOB_FLAG_ISCOMMAND)
/datum/job/proc/job_is_xp_locked()
if(!CONFIG_GET(flag/use_exp_restrictions_command) && job_flags & JOB_FLAG_ISCOMMAND)
return FALSE
if(!CONFIG_GET(flag/use_exp_restrictions_other) && !(job.job_flags & JOB_FLAG_ISCOMMAND))
if(!CONFIG_GET(flag/use_exp_restrictions_other) && !(job_flags & JOB_FLAG_ISCOMMAND))
return FALSE
return TRUE


/client/proc/calc_exp_type(exptype)
var/list/explist = prefs.exp.Copy()
var/amount = 0
var/list/typelist = GLOB.exp_jobsmap[exptype]
if(!typelist)
return 0
for(var/job in typelist["titles"])
if(job in explist)
amount += explist[job]
return amount


/client/proc/get_exp_report()
if(!CONFIG_GET(flag/use_exp_tracking))
return "Tracking is disabled in the server configuration file."
var/list/play_records = prefs.exp
if(!length(play_records))
set_exp_from_db()
play_records = prefs.exp
if(!length(play_records))
return "[key] has no records."
var/return_text = list()
return_text += "<UL>"
var/list/exp_data = list()
for(var/category in SSjob.name_occupations)
if(!(category in GLOB.jobs_regular_all))
continue
if(play_records[category])
exp_data[category] = text2num(play_records[category])
else
exp_data[category] = 0
for(var/category in GLOB.exp_specialmap)
if(category == EXP_TYPE_SPECIAL)
if(GLOB.exp_specialmap[category])
for(var/innercat in GLOB.exp_specialmap[category])
if(play_records[innercat])
exp_data[innercat] = text2num(play_records[innercat])
else
exp_data[innercat] = 0
else
if(play_records[category])
exp_data[category] = text2num(play_records[category])
else
exp_data[category] = 0

for(var/dep in exp_data)
if(exp_data[dep] <= 0)
continue
if(exp_data[EXP_TYPE_LIVING] > 0 && (dep == EXP_TYPE_GHOST || dep == EXP_TYPE_LIVING))
var/percentage = num2text(round(exp_data[dep] / (exp_data[EXP_TYPE_LIVING] + exp_data[EXP_TYPE_GHOST]) * 100))
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] ([percentage]%) total.</LI>"
else if(exp_data[EXP_TYPE_LIVING] > 0 && dep != EXP_TYPE_ADMIN)
var/percentage = num2text(round(exp_data[dep] / exp_data[EXP_TYPE_LIVING] * 100))
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] ([percentage]%) while alive.</LI>"
else
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] </LI>"

for(var/mob_type AS in GLOB.xeno_caste_datums)
var/datum/xeno_caste/caste_type = GLOB.xeno_caste_datums[mob_type][XENO_UPGRADE_BASETYPE]
return_text += "<LI>[caste_type.caste_name] [get_exp_format(play_records[caste_type.caste_name])] while alive.</LI>"

if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_other_rights(src, R_ADMIN, FALSE))
return_text += "<LI>Admin (all jobs auto-unlocked)</LI>"
return_text += "</UL>"
var/list/jobs_locked = list()
var/list/jobs_unlocked = list()
for(var/j in SSjob.joinable_occupations)
var/datum/job/job = j
if(job.exp_requirements && job.exp_type)
if(!job_is_xp_locked(job))
continue
else if(!job.required_playtime_remaining(mob.client))
jobs_unlocked += job.title
else
var/xp_req = job.get_exp_req_amount()
jobs_locked += "[job.title] [get_exp_format(text2num(calc_exp_type(job.get_exp_req_type())))] / [get_exp_format(xp_req)] as [job.get_exp_req_type()])"
if(length(jobs_unlocked))
return_text += "<BR><BR>Jobs Unlocked:<UL><LI>"
return_text += jobs_unlocked.Join("</LI><LI>")
return_text += "</LI></UL>"
if(length(jobs_locked))
return_text += "<BR><BR>Jobs Not Unlocked:<UL><LI>"
return_text += jobs_locked.Join("</LI><LI>")
return_text += "</LI></UL>"
return return_text


/client/proc/get_exp(role)
var/list/play_records = prefs.exp
if(!length(play_records))
return 0
return text2num(play_records[role])

/client/proc/get_exp_living(pure_numeric = FALSE)
if(!prefs.exp)
return pure_numeric ? 0 :"No data"
var/exp_living = text2num(prefs.exp[EXP_TYPE_LIVING])
return pure_numeric ? exp_living : get_exp_format(exp_living)


/proc/get_exp_format(expnum)
if(expnum > 60)
return num2text(round(expnum / 60)) + "h" + num2text(round(expnum % 60)) + "m"
else if(expnum > 0)
return num2text(expnum) + "m"
else
return "0h"


/proc/update_exp(mins, ann = FALSE)
if(!SSdbcore.Connect())
return -1
for(var/client/L in GLOB.clients)
if(L.is_afk())
continue
L.update_exp_list(mins, ann)


/proc/update_exp_db()
set waitfor = FALSE
var/list/old_minutes = GLOB.exp_to_update
GLOB.exp_to_update = null
SSdbcore.MassInsert(format_table_name("role_time"), old_minutes, duplicate_key = "ON DUPLICATE KEY UPDATE minutes = minutes + VALUES(minutes)")


/client/proc/set_exp_from_db()
if(!CONFIG_GET(flag/use_exp_tracking))
return -1
if(!SSdbcore.Connect())
return -1
var/datum/db_query/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = :ckey", list("ckey" = ckey))
if(!exp_read.Execute(async = TRUE))
qdel(exp_read)
return -1
var/list/play_records = list()
while(exp_read.NextRow())
play_records[exp_read.item[1]] = text2num(exp_read.item[2])
qdel(exp_read)

for(var/rtype in SSjob.name_occupations)
if(!play_records[rtype])
play_records[rtype] = 0
for(var/rtype in GLOB.exp_specialmap)
if(!play_records[rtype])
play_records[rtype] = 0

prefs.exp = play_records


/client/proc/update_exp_list(minutes, announce_changes = FALSE)
if(!CONFIG_GET(flag/use_exp_tracking))
return -1
if(!SSdbcore.Connect())
return -1
if(!isnum(minutes))
return -1
var/list/play_records = list()

if(holder && !holder.deadmined)
play_records[EXP_TYPE_ADMIN] += minutes
if(announce_changes)
to_chat(src,span_notice("You got: [minutes] Admin EXP!"))

if(isliving(mob))
var/mob/living/living_mob = mob
if(mob.stat != DEAD)
play_records[EXP_TYPE_LIVING] += minutes
if(announce_changes)
to_chat(src,span_notice("You got: [minutes] Living EXP!"))
if(living_mob.job)
if(!istype(living_mob.job, /datum/job/fallen))
if(isxeno(living_mob))
var/mob/living/carbon/xenomorph/xeno = living_mob
play_records[xeno.xeno_caste.caste_name] += minutes
play_records[living_mob.job.title] += minutes
if(announce_changes)
to_chat(src,span_notice("You got: [minutes] [living_mob.job] EXP!"))
else
play_records["Valhalla"] += minutes
else
play_records["Unknown"] += minutes
else
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
to_chat(src,span_notice("You got: [minutes] Ghost EXP!"))
else if(isobserver(mob))
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
to_chat(src,span_notice("You got: [minutes] Ghost EXP!"))
else if(minutes) //Let "refresh" checks go through
return

for(var/jtype in play_records)
var/jvalue = play_records[jtype]
if (!jvalue)
continue
if (!isnum(jvalue))
CRASH("invalid job value [jtype]:[jvalue]")
LAZYINITLIST(GLOB.exp_to_update)
GLOB.exp_to_update.Add(list(list(
"job" = jtype,
"ckey" = ckey,
"minutes" = jvalue)))
prefs.exp[jtype] += jvalue
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(update_exp_db)), 20, TIMER_OVERRIDE|TIMER_UNIQUE)


/proc/queen_age_check(client/C)
if(!C.prefs?.exp)
return FALSE
if(!CONFIG_GET(flag/use_exp_tracking))
return FALSE
if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_other_rights(C, R_ADMIN, FALSE))
return FALSE
var/my_exp = C.prefs.exp[ROLE_XENOMORPH]
return my_exp < XP_REQ_UNSEASONED
/proc/get_exp_format(minutes)
var/hours = round(minutes / 60)
minutes = round(minutes % 60)
return hours > 0 ? "[hours]h [minutes]m" : "[minutes]m"
Loading