mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-30 07:27:57 +01:00
Update 6
- 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:
@@ -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"
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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> "
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user