- Split EXP_TYPE_CREW into EXP_TYPE_LIVING (all living mobs) and
EXP_TYPE_CREW (actual crew positions). Job unlocks use EXP_TYPE_CREW.
General playtime reports use EXP_TYPE_LIVING. Playing corgi doesn't help
unlock jobs, but it does show in your stats.
- Added tracking for karma-locked jobs as a department in stats.
- Added quite a few safety checks.
- Split the per-client part of update_exp into update_exp_client
- Added new config option to let admins bypass the system, intended for
testing
- Moved defines to code\__DEFINES\preferences.dm
This commit is contained in:
Kyep
2016-08-06 14:39:35 -07:00
parent 12209a360b
commit e1dccb435b
7 changed files with 93 additions and 80 deletions
+16
View File
@@ -27,3 +27,19 @@
#define CHAT_NO_ADMINLOGS 16384
#define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC|MEMBER_PUBLIC)
// Playtime tracking system, see jobs_exp.dm
#define EXP_TYPE_LIVING "Living"
#define EXP_TYPE_CREW "Crew"
#define EXP_TYPE_COMMAND "Command"
#define EXP_TYPE_ENGINEERING "Engineering"
#define EXP_TYPE_MEDICAL "Medical"
#define EXP_TYPE_SCIENCE "Science"
#define EXP_TYPE_SUPPLY "Supply"
#define EXP_TYPE_SECURITY "Security"
#define EXP_TYPE_SILICON "Silicon"
#define EXP_TYPE_SERVICE "Service"
#define EXP_TYPE_WHITELIST "Whitelist"
#define EXP_TYPE_SPECIAL "Special"
#define EXP_TYPE_GHOST "Ghost"
#define EXP_TYPE_EXEMPT "Exempt"
+4
View File
@@ -131,6 +131,7 @@
var/use_exp_restrictions_heads = 0
var/use_exp_restrictions_heads_hours = 0
var/use_exp_restrictions_other = 0
var/use_exp_restrictions_admin_bypass = 0
var/simultaneous_pm_warning_timeout = 100
@@ -256,6 +257,9 @@
if("use_exp_restrictions_other")
config.use_exp_restrictions_other = 1
if("use_exp_restrictions_admin_bypass")
config.use_exp_restrictions_admin_bypass = 1
if("jobs_have_minimal_access")
config.jobs_have_minimal_access = 1
+59 -72
View File
@@ -1,27 +1,5 @@
// Defines
#define EXP_TYPE_CREW "Crew"
#define EXP_TYPE_COMMAND "Command"
#define EXP_TYPE_ENGINEERING "Engineering"
#define EXP_TYPE_SECURITY "Security"
#define EXP_TYPE_SILICON "Silicon"
#define EXP_TYPE_SERVICE "Service"
#define EXP_TYPE_MEDICAL "Medical"
#define EXP_TYPE_SCIENCE "Science"
#define EXP_TYPE_SUPPLY "Supply"
#define EXP_TYPE_SPECIAL "Special"
#define EXP_TYPE_GHOST "Ghost"
#define EXP_TYPE_EXEMPT "Exempt"
// Globals, Defines, Etc
// Admin Verbs
/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are.
set category = "Admin"
set name = "Check Player Playtime"
@@ -29,20 +7,21 @@
return
var/msg = "<html><head><title>Playtime Report</title></head><body>Playtime:<BR><UL>"
for(var/client/C in clients)
msg += "<LI> - [key_name_admin(C)]: <A href='?_src_=holder;getplaytimewindow=\ref[C.mob]'>" + C.get_exp_general() + "</a></LI>"
msg += "<LI> - [key_name_admin(C)]: <A href='?_src_=holder;getplaytimewindow=\ref[C.mob]'>" + C.get_exp_living() + "</a></LI>"
msg += "</UL></BODY></HTML>"
src << browse(msg, "window=Player_playtime_check")
/datum/admins/proc/cmd_show_exp_panel(var/client/C)
if (!C)
if(!C)
to_chat(usr, "ERROR: Mob not found.")
return
if(!check_rights(R_ADMIN))
return
var/body = "<html><head><title>Playtime for [C.key]</title></head><BODY><BR>Playtime:"
body += C.get_exp_report()
body += "</BODY></HTML>"
usr << browse(body, "window=playerplaytime;size=550x615")
usr << browse(body, "window=playerplaytime[C.ckey];size=550x615")
// Procs
@@ -55,7 +34,7 @@
return 0
if(!job_is_xp_locked(src.title))
return 0
if(check_rights(R_ADMIN, 0, C.mob))
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])
@@ -107,12 +86,13 @@
if(exp_data[dep] > 0)
if(dep == EXP_TYPE_EXEMPT)
return_text += "<LI>Exempt (all jobs auto-unlocked)</LI>"
else if(exp_data[EXP_TYPE_CREW] > 0)
var/my_pc = num2text(round(exp_data[dep]/exp_data[EXP_TYPE_CREW]*100))
else if(exp_data[EXP_TYPE_LIVING] > 0)
var/my_pc = num2text(round(exp_data[dep]/exp_data[EXP_TYPE_LIVING]*100))
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] ([my_pc]%)</LI>"
else
return_text += "<LI>[dep] [get_exp_format(exp_data[dep])] </LI>"
if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, mob))
return_text += "<LI>Admin (all jobs auto-unlocked)</LI>"
return_text += "</UL>"
var/list/jobs_locked = list()
var/list/jobs_unlocked = list()
@@ -140,9 +120,9 @@
return return_text
/client/proc/get_exp_general()
/client/proc/get_exp_living()
var/list/play_records = params2list(prefs.exp)
var/exp_gen = text2num(play_records[EXP_TYPE_CREW])
var/exp_gen = text2num(play_records[EXP_TYPE_LIVING])
return get_exp_format(exp_gen)
/proc/get_exp_format(var/expnum)
@@ -153,53 +133,60 @@
else
return "0h"
/proc/update_exp(var/minutes, var/announce_changes = 0)
/proc/update_exp(var/mins, var/ann = 0)
if(!establish_db_connection())
return -1
spawn(0)
for(var/client/C in clients)
if(C.inactivity >= (10 MINUTES))
for(var/client/L in clients)
if(L.inactivity >= (10 MINUTES))
continue
var/DBQuery/exp_read = dbcon.NewQuery("SELECT exp FROM [format_table_name("player")] WHERE ckey='[C.ckey]'")
exp_read.Execute()
var/list/read_records = list()
while(exp_read.NextRow())
read_records = params2list(exp_read.item[1])
var/list/play_records = list()
for(var/rtype in exp_jobsmap)
if(text2num(read_records[rtype]))
play_records[rtype] = text2num(read_records[rtype])
else
play_records[rtype] = 0
if(C.mob.stat == CONSCIOUS && C.mob.mind.assigned_role)
play_records[EXP_TYPE_CREW] += minutes
if(announce_changes)
to_chat(C.mob,"<span class='notice'>You got: [minutes] General EXP!")
for(var/cat in exp_jobsmap)
if(exp_jobsmap[cat]["titles"])
if(C.mob.mind.assigned_role in exp_jobsmap[cat]["titles"])
play_records[cat] += minutes
if(announce_changes)
to_chat(C.mob,"<span class='notice'>You got: [minutes] [cat] EXP!")
if(C.mob.mind.special_role)
play_records[EXP_TYPE_SPECIAL] += minutes
if(announce_changes)
to_chat(C.mob,"<span class='notice'>You got: [minutes] Special EXP!")
else if(isobserver(C.mob))
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
to_chat(C.mob,"<span class='notice'>You got: [minutes] Ghost EXP!")
else
return
var/new_exp = list2params(play_records)
C.prefs.exp = new_exp
new_exp = sanitizeSQL(new_exp)
var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("player")] SET exp = '[new_exp]' WHERE ckey='[C.ckey]'")
update_query.Execute()
spawn(0)
update_exp_client(L, mins, ann)
sleep(10)
/proc/update_exp_client(var/client/C, var/minutes, var/announce_changes = 0)
if(!C ||!C.ckey)
return
var/DBQuery/exp_read = dbcon.NewQuery("SELECT exp FROM [format_table_name("player")] WHERE ckey='[C.ckey]'")
exp_read.Execute()
var/list/read_records = list()
var/hasread = 0
while(exp_read.NextRow())
read_records = params2list(exp_read.item[1])
hasread = 1
if(!hasread)
return
var/list/play_records = list()
for(var/rtype in exp_jobsmap)
if(text2num(read_records[rtype]))
play_records[rtype] = text2num(read_records[rtype])
else
play_records[rtype] = 0
if(C.mob.stat == CONSCIOUS && C.mob.mind.assigned_role)
play_records[EXP_TYPE_LIVING] += minutes
if(announce_changes)
to_chat(C.mob,"<span class='notice'>You got: [minutes] Living EXP!")
for(var/cat in exp_jobsmap)
if(exp_jobsmap[cat]["titles"])
if(C.mob.mind.assigned_role in exp_jobsmap[cat]["titles"])
play_records[cat] += minutes
if(announce_changes)
to_chat(C.mob,"<span class='notice'>You got: [minutes] [cat] EXP!")
if(C.mob.mind.special_role)
play_records[EXP_TYPE_SPECIAL] += minutes
if(announce_changes)
to_chat(C.mob,"<span class='notice'>You got: [minutes] Special EXP!")
else if(isobserver(C.mob))
play_records[EXP_TYPE_GHOST] += minutes
if(announce_changes)
to_chat(C.mob,"<span class='notice'>You got: [minutes] Ghost EXP!")
else
return
var/new_exp = list2params(play_records)
C.prefs.exp = new_exp
new_exp = sanitizeSQL(new_exp)
var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("player")] SET exp = '[new_exp]' WHERE ckey='[C.ckey]'")
update_query.Execute()
/hook/roundstart/proc/exptimer()
if(!config.sql_enabled || !config.use_exp_tracking)
+8 -6
View File
@@ -184,16 +184,18 @@ var/list/whitelisted_positions = list(
return titles
var/global/list/exp_jobsmap = list(
EXP_TYPE_CREW = list(), // all playtime from all jobs, together
EXP_TYPE_LIVING = list(), // all living mobs
EXP_TYPE_CREW = list(titles = command_positions + engineering_positions + medical_positions + science_positions + support_positions + supply_positions + security_positions + civilian_positions + whitelisted_positions), // crew positions
EXP_TYPE_COMMAND = list(titles = command_positions),
EXP_TYPE_ENGINEERING = list(titles = engineering_positions),
EXP_TYPE_SECURITY = list(titles = security_positions),
EXP_TYPE_SILICON = list(titles = nonhuman_positions),
EXP_TYPE_SERVICE = list(titles = service_positions),
EXP_TYPE_MEDICAL = list(titles = medical_positions),
EXP_TYPE_SCIENCE = list(titles = science_positions),
EXP_TYPE_SUPPLY = list(titles = supply_positions),
EXP_TYPE_SPECIAL = list(), // special_role
EXP_TYPE_GHOST = list(), // dead/observer
EXP_TYPE_SECURITY = list(titles = security_positions),
EXP_TYPE_SILICON = list(titles = nonhuman_positions),
EXP_TYPE_SERVICE = list(titles = service_positions),
EXP_TYPE_WHITELIST = list(titles = whitelisted_positions), // karma-locked jobs
EXP_TYPE_SPECIAL = list(), // antags, ERT, etc
EXP_TYPE_GHOST = list(), // dead people, observers
EXP_TYPE_EXEMPT = list() // special grandfather setting
)
+1 -1
View File
@@ -43,7 +43,7 @@ var/global/nologevent = 0
if(M.client)
body += " played by <b>[M.client]</b> "
body += "\[<A href='?_src_=holder;editrights=rank;ckey=[M.ckey]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\] "
body += "\[<A href='?_src_=holder;getplaytimewindow=\ref[M]'>" + M.client.get_exp_general() + "</a>\]"
body += "\[<A href='?_src_=holder;getplaytimewindow=\ref[M]'>" + M.client.get_exp_living() + "</a>\]"
if(istype(M, /mob/new_player))
body += " <B>Hasn't Entered Game</B> "
+3 -1
View File
@@ -2017,9 +2017,11 @@
fax_panel(usr)
else if(href_list["getplaytimewindow"])
if(!check_rights(R_ADMIN)) return
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["getplaytimewindow"])
if(!M)
to_chat(usr, "ERROR: Mob not found.")
return
cmd_show_exp_panel(M.client)
+2
View File
@@ -20,10 +20,12 @@ JOBS_HAVE_MINIMAL_ACCESS
## USE_EXP_TRACKING enables playtime/exp tracking. REQUIRES DATABASE TO BE ENABLED.
## USE_EXP_RESTRICTIONS_HEADS enables playtime/exp requirements for head jobs. If USE_EXP_RESTRICTIONS_HEADS_HOURS is enabled also, it uses that value for their time requirements. If not, it goes by the values defined on their job definitions in code.
## USE_EXP_RESTRICTIONS_OTHER enables playtime/exp requirements for some dangerous non-head jobs, like engineer, scientist, security officer, etc. The requirements for these jobs are always taken from code.
## USE_EXP_RESTRICTIONS_ADMIN_BYPASS lets admins always bypass the restrictions. Useful to turn off for testing.
#USE_EXP_TRACKING
#USE_EXP_RESTRICTIONS_HEADS
#USE_EXP_RESTRICTIONS_HEADS_HOURS 15
#USE_EXP_RESTRICTIONS_OTHER
#USE_EXP_RESTRICTIONS_ADMIN_BYPASS
## Unhash this entry to have certain antagonist roles require your account to be at least a certain number of days old to select. You can configure the exact age requirement for different antag roles by editing special_role_times in /code/modules/client/preferences.dm.
## See USE_AGE_RESTRICTION_FOR_JOBS for more information