281 lines
8.9 KiB
Plaintext
281 lines
8.9 KiB
Plaintext
GLOBAL_LIST_EMPTY(exp_to_update)
|
|
GLOBAL_PROTECT(exp_to_update)
|
|
|
|
|
|
// Procs
|
|
/datum/job/proc/required_playtime_remaining(client/C)
|
|
if(!C)
|
|
return 0
|
|
if(!CONFIG_GET(flag/use_exp_tracking))
|
|
return 0
|
|
if(!exp_requirements || !exp_type)
|
|
return 0
|
|
if(!job_is_xp_locked(src.title))
|
|
return 0
|
|
if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_rights_for(C,R_ADMIN))
|
|
return 0
|
|
var/isexempt = C.prefs.db_flags & DB_FLAG_EXEMPT
|
|
if(isexempt)
|
|
return 0
|
|
var/my_exp = C.calc_exp_type(get_exp_req_type())
|
|
var/job_requirement = get_exp_req_amount()
|
|
if(my_exp >= job_requirement)
|
|
return 0
|
|
else
|
|
return (job_requirement - my_exp)
|
|
|
|
/datum/job/proc/get_exp_req_amount()
|
|
if(title in (GLOB.command_positions | list("AI")))
|
|
var/uerhh = CONFIG_GET(number/use_exp_restrictions_heads_hours)
|
|
if(uerhh)
|
|
return uerhh * 60
|
|
return exp_requirements
|
|
|
|
/datum/job/proc/get_exp_req_type()
|
|
if(title in (GLOB.command_positions | list("AI")))
|
|
if(CONFIG_GET(flag/use_exp_restrictions_heads_department) && exp_type_department)
|
|
return exp_type_department
|
|
return exp_type
|
|
|
|
/proc/job_is_xp_locked(jobtitle)
|
|
if(!CONFIG_GET(flag/use_exp_restrictions_heads) && jobtitle in (GLOB.command_positions | list("AI")))
|
|
return FALSE
|
|
if(!CONFIG_GET(flag/use_exp_restrictions_other) && !(jobtitle in (GLOB.command_positions | list("AI"))))
|
|
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 -1
|
|
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(!play_records.len)
|
|
set_exp_from_db()
|
|
play_records = prefs.exp
|
|
if(!play_records.len)
|
|
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(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 || category == EXP_TYPE_ANTAG)
|
|
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
|
|
if(prefs.db_flags & DB_FLAG_EXEMPT)
|
|
return_text += "<LI>Exempt (all jobs auto-unlocked)</LI>"
|
|
|
|
for(var/dep in exp_data)
|
|
if(exp_data[dep] > 0)
|
|
if(exp_data[EXP_TYPE_LIVING] > 0)
|
|
var/percentage = num2text(round(exp_data[dep]/exp_data[EXP_TYPE_LIVING]*100))
|
|
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] ([percentage]%)</LI>"
|
|
else
|
|
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] </LI>"
|
|
if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_rights_for(src,R_ADMIN))
|
|
return_text += "<LI>Admin (all jobs auto-unlocked)</LI>"
|
|
return_text += "</UL>"
|
|
var/list/jobs_locked = list()
|
|
var/list/jobs_unlocked = list()
|
|
for(var/datum/job/job in SSjob.occupations)
|
|
if(job.exp_requirements && job.exp_type)
|
|
if(!job_is_xp_locked(job.title))
|
|
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(jobs_unlocked.len)
|
|
return_text += "<BR><BR>Jobs Unlocked:<UL><LI>"
|
|
return_text += jobs_unlocked.Join("</LI><LI>")
|
|
return_text += "</LI></UL>"
|
|
if(jobs_locked.len)
|
|
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_living()
|
|
if(!prefs.exp)
|
|
return "No data"
|
|
var/exp_living = text2num(prefs.exp[EXP_TYPE_LIVING])
|
|
return get_exp_format(exp_living)
|
|
|
|
/proc/get_exp_format(expnum)
|
|
if(expnum > 60)
|
|
return num2text(round(expnum / 60)) + "h"
|
|
else if(expnum > 0)
|
|
return num2text(expnum) + "m"
|
|
else
|
|
return "0h"
|
|
|
|
/datum/controller/subsystem/blackbox/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)
|
|
|
|
/datum/controller/subsystem/blackbox/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, "ON DUPLICATE KEY UPDATE minutes = minutes + VALUES(minutes)")
|
|
|
|
//resets a client's exp to what was in the db.
|
|
/client/proc/set_exp_from_db()
|
|
if(!CONFIG_GET(flag/use_exp_tracking))
|
|
return -1
|
|
if(!SSdbcore.Connect())
|
|
return -1
|
|
var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(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
|
|
|
|
//updates player db flags
|
|
/client/proc/update_flag_db(newflag, state = FALSE)
|
|
|
|
if(!SSdbcore.Connect())
|
|
return -1
|
|
|
|
if(!set_db_player_flags())
|
|
return -1
|
|
|
|
if((prefs.db_flags & newflag) && !state)
|
|
prefs.db_flags &= ~newflag
|
|
else
|
|
prefs.db_flags |= newflag
|
|
|
|
var/datum/DBQuery/flag_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET flags = '[prefs.db_flags]' WHERE ckey='[sanitizeSQL(ckey)]'")
|
|
|
|
if(!flag_update.Execute())
|
|
qdel(flag_update)
|
|
return -1
|
|
qdel(flag_update)
|
|
|
|
|
|
/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(isliving(mob))
|
|
if(mob.stat != DEAD)
|
|
var/rolefound = FALSE
|
|
play_records[EXP_TYPE_LIVING] += minutes
|
|
if(announce_changes)
|
|
to_chat(src,"<span class='notice'>You got: [minutes] Living EXP!</span>")
|
|
if(mob.mind.assigned_role)
|
|
for(var/job in SSjob.name_occupations)
|
|
if(mob.mind.assigned_role == job)
|
|
rolefound = TRUE
|
|
play_records[job] += minutes
|
|
if(announce_changes)
|
|
to_chat(src,"<span class='notice'>You got: [minutes] [job] EXP!</span>")
|
|
if(!rolefound)
|
|
for(var/role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])
|
|
if(mob.mind.assigned_role == role)
|
|
rolefound = TRUE
|
|
play_records[role] += minutes
|
|
if(announce_changes)
|
|
to_chat(mob,"<span class='notice'>You got: [minutes] [role] EXP!</span>")
|
|
if(mob.mind.special_role && !(mob.mind.datum_flags & DF_VAR_EDITED))
|
|
var/trackedrole = mob.mind.special_role
|
|
play_records[trackedrole] += minutes
|
|
if(announce_changes)
|
|
to_chat(src,"<span class='notice'>You got: [minutes] [trackedrole] EXP!</span>")
|
|
if(!rolefound)
|
|
play_records["Unknown"] += minutes
|
|
else
|
|
if(holder && !holder.deadmined)
|
|
play_records[EXP_TYPE_ADMIN] += minutes
|
|
if(announce_changes)
|
|
to_chat(src,"<span class='notice'>You got: [minutes] Admin EXP!</span>")
|
|
else
|
|
play_records[EXP_TYPE_GHOST] += minutes
|
|
if(announce_changes)
|
|
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
|
|
else if(isobserver(mob))
|
|
play_records[EXP_TYPE_GHOST] += minutes
|
|
if(announce_changes)
|
|
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
|
|
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" = "'[sanitizeSQL(jtype)]'",
|
|
"ckey" = "'[sanitizeSQL(ckey)]'",
|
|
"minutes" = jvalue)))
|
|
prefs.exp[jtype] += jvalue
|
|
addtimer(CALLBACK(SSblackbox,/datum/controller/subsystem/blackbox/proc/update_exp_db),20,TIMER_OVERRIDE|TIMER_UNIQUE)
|
|
|
|
|
|
//ALWAYS call this at beginning to any proc touching player flags, or your database admin will probably be mad
|
|
/client/proc/set_db_player_flags()
|
|
if(!SSdbcore.Connect())
|
|
return FALSE
|
|
|
|
var/datum/DBQuery/flags_read = SSdbcore.NewQuery("SELECT flags FROM [format_table_name("player")] WHERE ckey='[ckey]'")
|
|
|
|
if(!flags_read.Execute(async = TRUE))
|
|
qdel(flags_read)
|
|
return FALSE
|
|
|
|
if(flags_read.NextRow())
|
|
prefs.db_flags = text2num(flags_read.item[1])
|
|
else if(isnull(prefs.db_flags))
|
|
prefs.db_flags = 0 //This PROBABLY won't happen, but better safe than sorry.
|
|
qdel(flags_read)
|
|
return TRUE
|