mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Adds mentors
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
GLOBAL_LIST_EMPTY(admins) //all clients whom are admins
|
GLOBAL_LIST_EMPTY(admins) //all clients whom are admins
|
||||||
GLOBAL_PROTECT(admins)
|
GLOBAL_PROTECT(admins)
|
||||||
|
GLOBAL_LIST_EMPTY(mentors)
|
||||||
|
GLOBAL_PROTECT(mentors)
|
||||||
GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb.
|
GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb.
|
||||||
GLOBAL_LIST_EMPTY(stealthminID)
|
GLOBAL_LIST_EMPTY(stealthminID)
|
||||||
GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
|
GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -113,7 +113,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
|||||||
s["players"] = 0
|
s["players"] = 0
|
||||||
s["stationtime"] = stationtime2text()
|
s["stationtime"] = stationtime2text()
|
||||||
s["roundduration"] = roundduration2text()
|
s["roundduration"] = roundduration2text()
|
||||||
s["map"] = strip_improper(using_map.full_name) //Done to remove the non-UTF-8 text macros
|
s["map"] = strip_improper(using_map.full_name) //Done to remove the non-UTF-8 text macros
|
||||||
|
|
||||||
if(input["status"] == "2") // Shiny new hip status.
|
if(input["status"] == "2") // Shiny new hip status.
|
||||||
var/active = 0
|
var/active = 0
|
||||||
@@ -509,12 +509,9 @@ var/world_topic_spam_protect_time = world.timeofday
|
|||||||
if (copytext(line, 1, 2) == ";")
|
if (copytext(line, 1, 2) == ";")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
var/title = "Mentor"
|
|
||||||
var/rights = admin_ranks[title]
|
|
||||||
|
|
||||||
var/ckey = copytext(line, 1, length(line)+1)
|
var/ckey = copytext(line, 1, length(line)+1)
|
||||||
var/datum/admins/D = new /datum/admins(title, rights, ckey)
|
var/datum/mentor/M = new /datum/mentor(ckey)
|
||||||
D.associate(GLOB.directory[ckey])
|
M.associate(GLOB.directory[ckey])
|
||||||
|
|
||||||
/world/proc/update_status()
|
/world/proc/update_status()
|
||||||
var/s = ""
|
var/s = ""
|
||||||
@@ -544,7 +541,7 @@ var/world_topic_spam_protect_time = world.timeofday
|
|||||||
features += config.abandon_allowed ? "respawn" : "no respawn"
|
features += config.abandon_allowed ? "respawn" : "no respawn"
|
||||||
|
|
||||||
features += config.persistence_disabled ? "persistence disabled" : "persistence enabled"
|
features += config.persistence_disabled ? "persistence disabled" : "persistence enabled"
|
||||||
|
|
||||||
features += config.persistence_ignore_mapload ? "persistence mapload disabled" : "persistence mapload enabled"
|
features += config.persistence_ignore_mapload ? "persistence mapload disabled" : "persistence mapload enabled"
|
||||||
|
|
||||||
if (config && config.allow_vote_mode)
|
if (config && config.allow_vote_mode)
|
||||||
@@ -694,7 +691,7 @@ var/failed_old_db_connections = 0
|
|||||||
|
|
||||||
if(dbcon_old?.IsConnected())
|
if(dbcon_old?.IsConnected())
|
||||||
results += "WARNING: dbcon_old is connected, not touching it, but is this intentional?"
|
results += "WARNING: dbcon_old is connected, not touching it, but is this intentional?"
|
||||||
|
|
||||||
if(!config.sql_enabled)
|
if(!config.sql_enabled)
|
||||||
results += "stopping because config.sql_enabled = false"
|
results += "stopping because config.sql_enabled = false"
|
||||||
else
|
else
|
||||||
@@ -703,7 +700,7 @@ var/failed_old_db_connections = 0
|
|||||||
results += "SUCCESS: set up a connection successfully with setup_database_connection()"
|
results += "SUCCESS: set up a connection successfully with setup_database_connection()"
|
||||||
else
|
else
|
||||||
results += "FAIL: failed to connect to the database with setup_database_connection()"
|
results += "FAIL: failed to connect to the database with setup_database_connection()"
|
||||||
|
|
||||||
results += "-- DB Reset End --"
|
results += "-- DB Reset End --"
|
||||||
to_world_log(results.Join("\n"))
|
to_world_log(results.Join("\n"))
|
||||||
*/
|
*/
|
||||||
@@ -713,11 +710,11 @@ var/failed_old_db_connections = 0
|
|||||||
if(!istype(GLOB.players_by_zlevel, /list))
|
if(!istype(GLOB.players_by_zlevel, /list))
|
||||||
GLOB.players_by_zlevel = new /list(world.maxz, 0)
|
GLOB.players_by_zlevel = new /list(world.maxz, 0)
|
||||||
GLOB.living_players_by_zlevel = new /list(world.maxz, 0)
|
GLOB.living_players_by_zlevel = new /list(world.maxz, 0)
|
||||||
|
|
||||||
while(GLOB.players_by_zlevel.len < world.maxz)
|
while(GLOB.players_by_zlevel.len < world.maxz)
|
||||||
GLOB.players_by_zlevel.len++
|
GLOB.players_by_zlevel.len++
|
||||||
GLOB.players_by_zlevel[GLOB.players_by_zlevel.len] = list()
|
GLOB.players_by_zlevel[GLOB.players_by_zlevel.len] = list()
|
||||||
|
|
||||||
GLOB.living_players_by_zlevel.len++
|
GLOB.living_players_by_zlevel.len++
|
||||||
GLOB.living_players_by_zlevel[GLOB.living_players_by_zlevel.len] = list()
|
GLOB.living_players_by_zlevel[GLOB.living_players_by_zlevel.len] = list()
|
||||||
|
|
||||||
@@ -759,10 +756,10 @@ var/global/game_id = null
|
|||||||
game_id = ""
|
game_id = ""
|
||||||
|
|
||||||
var/list/c = list(
|
var/list/c = list(
|
||||||
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
|
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
|
||||||
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
|
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
|
||||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
|
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
|
||||||
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
|
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
|
||||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"
|
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"
|
||||||
)
|
)
|
||||||
var/l = c.len
|
var/l = c.len
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ var/list/admin_verbs_default = list(
|
|||||||
/client/proc/cmd_admin_say, //VOREStation Add,
|
/client/proc/cmd_admin_say, //VOREStation Add,
|
||||||
/client/proc/cmd_mod_say, //VOREStation Add,
|
/client/proc/cmd_mod_say, //VOREStation Add,
|
||||||
/client/proc/cmd_event_say, //VOREStation Add,
|
/client/proc/cmd_event_say, //VOREStation Add,
|
||||||
|
/client/proc/cmd_mentor_ticket_panel,
|
||||||
|
/client/proc/cmd_mentor_say
|
||||||
// /client/proc/hide_verbs, //hides all our adminverbs, //VOREStation Remove,
|
// /client/proc/hide_verbs, //hides all our adminverbs, //VOREStation Remove,
|
||||||
// /client/proc/hide_most_verbs, //hides all our hideable adminverbs, //VOREStation Remove,
|
// /client/proc/hide_most_verbs, //hides all our hideable adminverbs, //VOREStation Remove,
|
||||||
// /client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, //VOREStation Remove,
|
// /client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, //VOREStation Remove,
|
||||||
@@ -122,7 +124,9 @@ var/list/admin_verbs_admin = list(
|
|||||||
/datum/admins/proc/set_uplink, //VOREStation Add,
|
/datum/admins/proc/set_uplink, //VOREStation Add,
|
||||||
/datum/admins/proc/sendFax,
|
/datum/admins/proc/sendFax,
|
||||||
/client/proc/despawn_player,
|
/client/proc/despawn_player,
|
||||||
/datum/admins/proc/view_feedback
|
/datum/admins/proc/view_feedback,
|
||||||
|
/client/proc/make_mentor,
|
||||||
|
/client/proc/unmake_mentor
|
||||||
)
|
)
|
||||||
|
|
||||||
var/list/admin_verbs_ban = list(
|
var/list/admin_verbs_ban = list(
|
||||||
|
|||||||
@@ -24,6 +24,17 @@
|
|||||||
else if(href_list["ahelp_tickets"])
|
else if(href_list["ahelp_tickets"])
|
||||||
GLOB.ahelp_tickets.BrowseTickets(text2num(href_list["ahelp_tickets"]))
|
GLOB.ahelp_tickets.BrowseTickets(text2num(href_list["ahelp_tickets"]))
|
||||||
|
|
||||||
|
if(href_list["mhelp"])
|
||||||
|
var/mhelp_ref = href_list["mhelp"]
|
||||||
|
var/datum/mentor_help/MH = locate(mhelp_ref)
|
||||||
|
if (MH)
|
||||||
|
MH.Action(href_list["mhelp_action"])
|
||||||
|
else
|
||||||
|
to_chat(usr, "Ticket [mhelp_ref] has been deleted!")
|
||||||
|
|
||||||
|
if (href_list["mhelp_tickets"])
|
||||||
|
GLOB.mhelp_tickets.BrowseTickets(text2num(href_list["mhelp_tickets"]))
|
||||||
|
|
||||||
if(href_list["dbsearchckey"] || href_list["dbsearchadmin"])
|
if(href_list["dbsearchckey"] || href_list["dbsearchadmin"])
|
||||||
|
|
||||||
var/adminckey = href_list["dbsearchadmin"]
|
var/adminckey = href_list["dbsearchadmin"]
|
||||||
|
|||||||
@@ -60,6 +60,14 @@
|
|||||||
cmd_admin_pm(C,null)
|
cmd_admin_pm(C,null)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(href_list["mentorhelp_msg"])
|
||||||
|
var/client/C = locate(href_list["mentorhelp_msg"])
|
||||||
|
if(ismob(C))
|
||||||
|
var/mob/M = C
|
||||||
|
C = M.client
|
||||||
|
cmd_mentor_pm(C, null)
|
||||||
|
return
|
||||||
|
|
||||||
if(href_list["irc_msg"])
|
if(href_list["irc_msg"])
|
||||||
if(!holder && received_irc_pm < world.time - 6000) //Worse they can do is spam IRC for 10 minutes
|
if(!holder && received_irc_pm < world.time - 6000) //Worse they can do is spam IRC for 10 minutes
|
||||||
to_chat(usr, "<span class='warning'>You are no longer able to use this, it's been more then 10 minutes since an admin on IRC has responded to you</span>")
|
to_chat(usr, "<span class='warning'>You are no longer able to use this, it's been more then 10 minutes since an admin on IRC has responded to you</span>")
|
||||||
@@ -123,6 +131,7 @@
|
|||||||
|
|
||||||
switch(href_list["_src_"])
|
switch(href_list["_src_"])
|
||||||
if("holder") hsrc = holder
|
if("holder") hsrc = holder
|
||||||
|
if("mentorholder") hsrc = (check_rights(R_ADMIN, 0) ? holder : mentorholder)
|
||||||
if("usr") hsrc = mob
|
if("usr") hsrc = mob
|
||||||
if("prefs") return prefs.process_link(usr,href_list)
|
if("prefs") return prefs.process_link(usr,href_list)
|
||||||
if("vars") return view_var_Topic(href,href_list,hsrc)
|
if("vars") return view_var_Topic(href,href_list,hsrc)
|
||||||
@@ -185,6 +194,10 @@
|
|||||||
GLOB.admins += src
|
GLOB.admins += src
|
||||||
holder.owner = src
|
holder.owner = src
|
||||||
|
|
||||||
|
mentorholder = mentor_datums[ckey]
|
||||||
|
if (mentorholder)
|
||||||
|
mentorholder.associate(GLOB.directory[ckey])
|
||||||
|
|
||||||
//preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum)
|
//preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum)
|
||||||
prefs = preferences_datums[ckey]
|
prefs = preferences_datums[ckey]
|
||||||
if(!prefs)
|
if(!prefs)
|
||||||
@@ -262,6 +275,9 @@
|
|||||||
if(holder)
|
if(holder)
|
||||||
holder.owner = null
|
holder.owner = null
|
||||||
GLOB.admins -= src
|
GLOB.admins -= src
|
||||||
|
if (mentorholder)
|
||||||
|
mentorholder.owner = null
|
||||||
|
GLOB.mentors -= src
|
||||||
GLOB.ahelp_tickets.ClientLogout(src)
|
GLOB.ahelp_tickets.ClientLogout(src)
|
||||||
GLOB.directory -= ckey
|
GLOB.directory -= ckey
|
||||||
GLOB.clients -= src
|
GLOB.clients -= src
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
else if(check_rights(R_STEALTH, FALSE, C)) // event managers //VOREStation Edit: Retired Staff
|
else if(check_rights(R_STEALTH, FALSE, C)) // event managers //VOREStation Edit: Retired Staff
|
||||||
category = R_EVENT
|
category = R_EVENT
|
||||||
num_event_managers_online++
|
num_event_managers_online++
|
||||||
|
|
||||||
temp += "\t[C] is a [C.holder.rank]"
|
temp += "\t[C] is a [C.holder.rank]"
|
||||||
if(holder)
|
if(holder)
|
||||||
if(C.holder.fakekey)
|
if(C.holder.fakekey)
|
||||||
@@ -121,6 +121,28 @@
|
|||||||
if(config.show_event_managers)
|
if(config.show_event_managers)
|
||||||
msg += "\n<b> Current Miscellaneous ([num_event_managers_online]):</b>\n" + eventMmsg
|
msg += "\n<b> Current Miscellaneous ([num_event_managers_online]):</b>\n" + eventMmsg
|
||||||
|
|
||||||
|
var/num_mentors_online = 0
|
||||||
|
var/mmsg = ""
|
||||||
|
|
||||||
|
for(var/client/C in GLOB.mentors)
|
||||||
|
num_mentors_online++
|
||||||
|
mmsg += "\t[C] is a Mentor"
|
||||||
|
if(holder)
|
||||||
|
if(isobserver(C.mob))
|
||||||
|
mmsg += " - Observing"
|
||||||
|
else if(istype(C.mob,/mob/new_player))
|
||||||
|
mmsg += " - Lobby"
|
||||||
|
else
|
||||||
|
mmsg += " - Playing"
|
||||||
|
|
||||||
|
if(C.is_afk())
|
||||||
|
var/seconds = C.last_activity_seconds()
|
||||||
|
mmsg += " (AFK - [round(seconds / 60)] minutes, [seconds % 60] seconds)"
|
||||||
|
mmsg += "\n"
|
||||||
|
|
||||||
|
if(config.show_mentors)
|
||||||
|
msg += "\n<b> Current Mentors ([num_mentors_online]):</b>\n" + mmsg
|
||||||
|
|
||||||
msg += "\n<span class='info'>Adminhelps are also sent to Discord. If no admins are available in game try anyway and an admin on Discord may see it and respond.</span>"
|
msg += "\n<span class='info'>Adminhelps are also sent to Discord. If no admins are available in game try anyway and an admin on Discord may see it and respond.</span>"
|
||||||
|
|
||||||
to_chat(src, msg)
|
to_chat(src, msg)
|
||||||
|
|||||||
238
code/modules/mentor/mentor.dm
Normal file
238
code/modules/mentor/mentor.dm
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
/client
|
||||||
|
var/datum/mentor/mentorholder = null
|
||||||
|
|
||||||
|
var/list/mentor_datums = list()
|
||||||
|
|
||||||
|
var/list/mentor_verbs_default = list(
|
||||||
|
/client/proc/cmd_mentor_ticket_panel,
|
||||||
|
/client/proc/cmd_mentor_say,
|
||||||
|
/client/proc/cmd_dementor
|
||||||
|
)
|
||||||
|
|
||||||
|
/datum/mentor
|
||||||
|
var/client/owner = null
|
||||||
|
|
||||||
|
/datum/mentor/New(ckey)
|
||||||
|
if(!ckey)
|
||||||
|
error("Mentor datum created without a ckey argument. Datum has been deleted")
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
mentor_datums[ckey] = src
|
||||||
|
|
||||||
|
/datum/mentor/proc/associate(client/C)
|
||||||
|
if(istype(C))
|
||||||
|
owner = C
|
||||||
|
owner.mentorholder = src
|
||||||
|
owner.add_mentor_verbs()
|
||||||
|
GLOB.mentors |= C
|
||||||
|
|
||||||
|
/datum/mentor/proc/disassociate()
|
||||||
|
if(owner)
|
||||||
|
GLOB.mentors -= owner
|
||||||
|
owner.remove_mentor_verbs()
|
||||||
|
owner.mentorholder = null
|
||||||
|
mentor_datums[owner.ckey] = null
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
/client/proc/add_mentor_verbs()
|
||||||
|
if(mentorholder)
|
||||||
|
verbs += mentor_verbs_default
|
||||||
|
|
||||||
|
/client/proc/remove_mentor_verbs()
|
||||||
|
if(mentorholder)
|
||||||
|
verbs -= mentor_verbs_default
|
||||||
|
|
||||||
|
/client/proc/make_mentor()
|
||||||
|
set category = "Special Verbs"
|
||||||
|
set name = "Make Mentor"
|
||||||
|
if(!holder)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error: Only administrators may use this command.</span>")
|
||||||
|
return
|
||||||
|
var/list/client/targets[0]
|
||||||
|
for(var/client/T in GLOB.clients)
|
||||||
|
targets["[T.key]"] = T
|
||||||
|
var/target = tgui_input_list(src,"Who do you want to make a mentor?","Make Mentor", sortList(targets))
|
||||||
|
if(!target)
|
||||||
|
return
|
||||||
|
var/client/C = targets[target]
|
||||||
|
if(C.holder)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error: You cannot make an admin a mentor.</span>")
|
||||||
|
return
|
||||||
|
var/datum/mentor/M = new /datum/mentor(C.ckey)
|
||||||
|
M.associate(C)
|
||||||
|
to_chat(C, "<span class='pm notice'>You have been granted mentorship.</span>")
|
||||||
|
to_chat(src, "<span class='pm notice'>You have made [C] a mentor.</span>")
|
||||||
|
log_admin("[key_name(src)] made [key_name(C)] a mentor.")
|
||||||
|
feedback_add_details("admin_verb","Make Mentor") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||||
|
|
||||||
|
/client/proc/unmake_mentor()
|
||||||
|
set category = "Special Verbs"
|
||||||
|
set name = "Unmake Mentor"
|
||||||
|
if(!holder)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error: Only administrators may use this command.</span>")
|
||||||
|
return
|
||||||
|
var/list/client/targets[0]
|
||||||
|
for(var/client/T in GLOB.mentors)
|
||||||
|
targets["[T.key]"] = T
|
||||||
|
var/target = tgui_input_list(src,"Which mentor do you want to unmake?","Unmake Mentor", sortList(targets))
|
||||||
|
if(!target)
|
||||||
|
return
|
||||||
|
var/client/C = targets[target]
|
||||||
|
C.mentorholder.disassociate()
|
||||||
|
to_chat(C, "<span class='pm warning'>Your mentorship has been revoked.</span>")
|
||||||
|
to_chat(src, "<span class='pm notice'>You have revoked [C]'s mentorship.</span>")
|
||||||
|
log_admin("[key_name(src)] revoked [key_name(C)]'s mentorship.")
|
||||||
|
feedback_add_details("admin_verb","Unmake Mentor") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||||
|
|
||||||
|
/client/proc/cmd_mentor_say(msg as text)
|
||||||
|
set category = "Admin"
|
||||||
|
set name ="Mentorsay"
|
||||||
|
|
||||||
|
//check rights
|
||||||
|
if (!src.mentorholder && !src.holder)
|
||||||
|
return
|
||||||
|
|
||||||
|
msg = sanitize(msg)
|
||||||
|
if (!msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
log_admin("Mentorsay: [key_name(src)]: [msg]")
|
||||||
|
|
||||||
|
for(var/client/C in GLOB.mentors)
|
||||||
|
to_chat(C, create_text_tag("mentor", "MENTOR:", C) + " <span class='mentor_channel'><span class='name'>[src]</span>: <span class='message'>[msg]</span></span>")
|
||||||
|
for(var/client/C in GLOB.admins)
|
||||||
|
to_chat(C, create_text_tag("mentor", "MENTOR:", C) + " <span class='mentor_channel'><span class='name'>[src]</span>: <span class='message'>[msg]</span></span>")
|
||||||
|
|
||||||
|
/datum/mentor/Topic(href, href_list)
|
||||||
|
if (usr.client != src.owner || (!usr.client.mentorholder))
|
||||||
|
log_admin("[key_name(usr)] tried to illegally use mentor functions.")
|
||||||
|
message_admins("[usr.key] tried to illegally use mentor functions.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(href_list["mhelp"])
|
||||||
|
var/mhelp_ref = href_list["mhelp"]
|
||||||
|
var/datum/mentor_help/MH = locate(mhelp_ref)
|
||||||
|
if (MH)
|
||||||
|
MH.Action(href_list["mhelp_action"])
|
||||||
|
else
|
||||||
|
to_chat(usr, "Ticket [mhelp_ref] has been deleted!")
|
||||||
|
|
||||||
|
if (href_list["mhelp_tickets"])
|
||||||
|
GLOB.mhelp_tickets.BrowseTickets(text2num(href_list["mhelp_tickets"]))
|
||||||
|
|
||||||
|
/client/proc/cmd_dementor()
|
||||||
|
set category = "Admin"
|
||||||
|
set name = "De-mentor"
|
||||||
|
|
||||||
|
if(tgui_alert(usr, "Confirm self-dementor for the round? You can't re-mentor yourself without someone promoting you.","Dementor",list("Yes","No")) == "Yes")
|
||||||
|
src.mentorholder.disassociate()
|
||||||
|
|
||||||
|
/client/proc/cmd_mhelp_reply(whom)
|
||||||
|
if(prefs.muted & MUTE_ADMINHELP)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error: Mentor-PM: You are unable to use admin PM-s (muted).</span>")
|
||||||
|
return
|
||||||
|
var/client/C
|
||||||
|
if(istext(whom))
|
||||||
|
C = GLOB.directory[whom]
|
||||||
|
else if(istype(whom,/client))
|
||||||
|
C = whom
|
||||||
|
if(!C)
|
||||||
|
if(holder)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error: Mentor-PM: Client not found.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/datum/mentor_help/MH = C.current_mentorhelp
|
||||||
|
|
||||||
|
if(MH)
|
||||||
|
message_mentors("<span class='mentor_channel'>[src] has started replying to [C]'s mentor help.</span>")
|
||||||
|
var/msg = tgui_input_text(src,"Message:", "Private message to [C]")
|
||||||
|
if (!msg)
|
||||||
|
message_mentors("<span class='mentor_channel'>[src] has cancelled their reply to [C]'s mentor help.</span>")
|
||||||
|
return
|
||||||
|
cmd_mentor_pm(whom, msg, MH)
|
||||||
|
|
||||||
|
/client/proc/cmd_mentor_pm(whom, msg, datum/mentor_help/MH)
|
||||||
|
set category = "Admin"
|
||||||
|
set name = "Mentor-PM"
|
||||||
|
set hidden = 1
|
||||||
|
|
||||||
|
if(prefs.muted & MUTE_ADMINHELP)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error: Mentor-PM: You are unable to use admin PM-s (muted).</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!(mentorholder || holder) && !current_mentorhelp)
|
||||||
|
to_chat(src, "<span class='pm warning'>You can no longer reply to this ticket, please open another one by using the Mentorhelp verb if need be.</span>")
|
||||||
|
to_chat(src, "<span class='pm notice'>Message: [msg]</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/client/recipient
|
||||||
|
|
||||||
|
if(istext(whom))
|
||||||
|
recipient = GLOB.directory[whom]
|
||||||
|
|
||||||
|
else if(istype(whom,/client))
|
||||||
|
recipient = whom
|
||||||
|
|
||||||
|
if(!recipient)
|
||||||
|
if(mentorholder)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error: Mentor-PM: Client not found.</span>")
|
||||||
|
to_chat(src, msg)
|
||||||
|
else
|
||||||
|
log_admin("Mentorhelp: [key_name(src)] sent [msg]")
|
||||||
|
current_mentorhelp.MessageNoRecipient(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
//get message text, limit it's length.and clean/escape html
|
||||||
|
if(!msg)
|
||||||
|
msg = tgui_input_text(src,"Message:", "Mentor-PM to [whom]")
|
||||||
|
|
||||||
|
if(!msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(prefs.muted & MUTE_ADMINHELP)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error: Mentor-PM: You are unable to use admin PM-s (muted).</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!recipient)
|
||||||
|
if(holder)
|
||||||
|
to_chat(src, "<span class='pm warning'>Error:Mentor-PM: Client not found.</span>")
|
||||||
|
else
|
||||||
|
log_admin("Mentorhelp: [key_name(src)] sent [msg]")
|
||||||
|
current_mentorhelp.MessageNoRecipient(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (src.handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||||
|
return
|
||||||
|
|
||||||
|
msg = trim(sanitize(copytext(msg,1,MAX_MESSAGE_LEN)))
|
||||||
|
if(!msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/interaction_message = "<span class='pm notice'>Mentor-PM from-<b>[src]</b> to-<b>[recipient]</b>: [msg]</span>"
|
||||||
|
|
||||||
|
if (recipient.current_mentorhelp && !(recipient.mentorholder || recipient.holder))
|
||||||
|
recipient.current_mentorhelp.AddInteraction(interaction_message)
|
||||||
|
if (src.current_mentorhelp && !(src.mentorholder || src.holder))
|
||||||
|
src.current_mentorhelp.AddInteraction(interaction_message)
|
||||||
|
|
||||||
|
// It's a little fucky if they're both mentors, but while admins may need to adminhelp I don't really see any reason a mentor would have to mentorhelp since you can literally just ask any other mentors online
|
||||||
|
if ((recipient.mentorholder || recipient.holder) && (src.mentorholder || src.holder))
|
||||||
|
if (recipient.current_mentorhelp)
|
||||||
|
recipient.current_mentorhelp.AddInteraction(interaction_message)
|
||||||
|
if (src.current_mentorhelp)
|
||||||
|
src.current_mentorhelp.AddInteraction(interaction_message)
|
||||||
|
|
||||||
|
to_chat(recipient, "<i><span class='mentor'>Mentor-PM from-<b><a href='?mentorhelp_msg=\ref[src]'>[src]</a></b>: [msg]</span></i>")
|
||||||
|
to_chat(src, "<i><span class='mentor'>Mentor-PM to-<b>[recipient]</b>: [msg]</span></i>")
|
||||||
|
|
||||||
|
log_admin("[key_name(src)] sent [msg] to [key_name(recipient)]")
|
||||||
|
|
||||||
|
if(recipient.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
|
||||||
|
recipient << 'sound/effects/mentorhelp.mp3'
|
||||||
|
|
||||||
|
for(var/client/C in GLOB.mentors)
|
||||||
|
if (C != recipient && C != src)
|
||||||
|
to_chat(C, interaction_message)
|
||||||
|
for(var/client/C in GLOB.admins)
|
||||||
|
if (C != recipient && C != src)
|
||||||
|
to_chat(C, interaction_message)
|
||||||
407
code/modules/mentor/mentorhelp.dm
Normal file
407
code/modules/mentor/mentorhelp.dm
Normal file
@@ -0,0 +1,407 @@
|
|||||||
|
/client/var/datum/mentor_help/current_mentorhelp
|
||||||
|
|
||||||
|
//
|
||||||
|
//TICKET MANAGER
|
||||||
|
//
|
||||||
|
|
||||||
|
GLOBAL_DATUM_INIT(mhelp_tickets, /datum/mentor_help_tickets, new)
|
||||||
|
|
||||||
|
/datum/mentor_help_tickets
|
||||||
|
var/list/active_tickets = list()
|
||||||
|
var/list/closed_tickets = list()
|
||||||
|
var/list/resolved_tickets = list()
|
||||||
|
|
||||||
|
var/obj/effect/statclick/mticket_list/astatclick = new(null, null, AHELP_ACTIVE)
|
||||||
|
var/obj/effect/statclick/mticket_list/cstatclick = new(null, null, AHELP_CLOSED)
|
||||||
|
var/obj/effect/statclick/mticket_list/rstatclick = new(null, null, AHELP_RESOLVED)
|
||||||
|
|
||||||
|
/datum/mentor_help_tickets/Destroy()
|
||||||
|
QDEL_LIST(active_tickets)
|
||||||
|
QDEL_LIST(closed_tickets)
|
||||||
|
QDEL_LIST(resolved_tickets)
|
||||||
|
QDEL_NULL(astatclick)
|
||||||
|
QDEL_NULL(cstatclick)
|
||||||
|
QDEL_NULL(rstatclick)
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
//private
|
||||||
|
/datum/mentor_help_tickets/proc/ListInsert(datum/mentor_help/new_ticket)
|
||||||
|
var/list/mticket_list
|
||||||
|
switch(new_ticket.state)
|
||||||
|
if(AHELP_ACTIVE)
|
||||||
|
mticket_list = active_tickets
|
||||||
|
if(AHELP_CLOSED)
|
||||||
|
mticket_list = closed_tickets
|
||||||
|
if(AHELP_RESOLVED)
|
||||||
|
mticket_list = resolved_tickets
|
||||||
|
else
|
||||||
|
CRASH("Invalid ticket state: [new_ticket.state]")
|
||||||
|
var/num_closed = mticket_list.len
|
||||||
|
if(num_closed)
|
||||||
|
for(var/I in 1 to num_closed)
|
||||||
|
var/datum/mentor_help/MH = mticket_list[I]
|
||||||
|
if(MH.id > new_ticket.id)
|
||||||
|
mticket_list.Insert(I, new_ticket)
|
||||||
|
return
|
||||||
|
mticket_list += new_ticket
|
||||||
|
|
||||||
|
//opens the ticket listings, only two states here
|
||||||
|
/datum/mentor_help_tickets/proc/BrowseTickets(state)
|
||||||
|
var/list/l2b
|
||||||
|
var/title
|
||||||
|
switch(state)
|
||||||
|
if(AHELP_ACTIVE)
|
||||||
|
l2b = active_tickets
|
||||||
|
title = "Active Tickets"
|
||||||
|
if(AHELP_RESOLVED)
|
||||||
|
l2b = resolved_tickets
|
||||||
|
title = "Resolved Tickets"
|
||||||
|
if(!l2b)
|
||||||
|
return
|
||||||
|
var/list/dat = list("<html><head><title>[title]</title></head>")
|
||||||
|
dat += "<A HREF='?_src_=mentorholder;mhelp_tickets=[state]'>Refresh</A><br><br>"
|
||||||
|
for(var/datum/mentor_help/MH as anything in l2b)
|
||||||
|
dat += "<span class='adminnotice'><span class='adminhelp'>Ticket #[MH.id]</span>: <A HREF='?_src_=mentorholder;mhelp=\ref[MH];mhelp_action=ticket'>[MH.initiator_ckey]: [MH.name]</A></span><br>"
|
||||||
|
|
||||||
|
usr << browse(dat.Join(), "window=mhelp_list[state];size=600x480")
|
||||||
|
|
||||||
|
//Tickets statpanel
|
||||||
|
/datum/mentor_help_tickets/proc/stat_entry()
|
||||||
|
var/num_disconnected = 0
|
||||||
|
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
||||||
|
for(var/datum/mentor_help/MH as anything in active_tickets)
|
||||||
|
if(MH.initiator)
|
||||||
|
stat("#[MH.id]. [MH.initiator_ckey]:", MH.statclick.update())
|
||||||
|
else
|
||||||
|
++num_disconnected
|
||||||
|
if(num_disconnected)
|
||||||
|
stat("Disconnected:", astatclick.update("[num_disconnected]"))
|
||||||
|
stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]"))
|
||||||
|
|
||||||
|
//Reassociate still open ticket if one exists
|
||||||
|
/datum/mentor_help_tickets/proc/ClientLogin(client/C)
|
||||||
|
C.current_mentorhelp = CKey2ActiveTicket(C.ckey)
|
||||||
|
if(C.current_mentorhelp)
|
||||||
|
C.current_mentorhelp.AddInteraction("Client reconnected.")
|
||||||
|
C.current_mentorhelp.initiator = C
|
||||||
|
|
||||||
|
//Dissasociate ticket
|
||||||
|
/datum/mentor_help_tickets/proc/ClientLogout(client/C)
|
||||||
|
if(C.current_mentorhelp)
|
||||||
|
C.current_mentorhelp.AddInteraction("Client disconnected.")
|
||||||
|
C.current_mentorhelp.initiator = null
|
||||||
|
C.current_mentorhelp = null
|
||||||
|
|
||||||
|
//Get a ticket given a ckey
|
||||||
|
/datum/mentor_help_tickets/proc/CKey2ActiveTicket(ckey)
|
||||||
|
for(var/datum/admin_help/MH as anything in active_tickets)
|
||||||
|
if(MH.initiator_ckey == ckey)
|
||||||
|
return MH
|
||||||
|
|
||||||
|
//
|
||||||
|
//TICKET LIST STATCLICK
|
||||||
|
//
|
||||||
|
|
||||||
|
/obj/effect/statclick/mticket_list
|
||||||
|
var/current_state
|
||||||
|
|
||||||
|
/obj/effect/statclick/mticket_list/New(loc, name, state)
|
||||||
|
current_state = state
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/effect/statclick/mticket_list/Click()
|
||||||
|
GLOB.mhelp_tickets.BrowseTickets(current_state)
|
||||||
|
|
||||||
|
//
|
||||||
|
//TICKET DATUM
|
||||||
|
//
|
||||||
|
|
||||||
|
/datum/mentor_help
|
||||||
|
var/id
|
||||||
|
var/name
|
||||||
|
var/state = AHELP_ACTIVE
|
||||||
|
|
||||||
|
var/opened_at
|
||||||
|
var/closed_at
|
||||||
|
|
||||||
|
var/client/initiator //semi-misnomer, it's the person who ahelped/was bwoinked
|
||||||
|
var/initiator_ckey
|
||||||
|
var/initiator_key_name
|
||||||
|
|
||||||
|
var/list/_interactions //use AddInteraction() or, preferably, admin_ticket_log()
|
||||||
|
|
||||||
|
var/obj/effect/statclick/ahelp/statclick
|
||||||
|
|
||||||
|
var/static/ticket_counter = 0
|
||||||
|
|
||||||
|
//call this on its own to create a ticket, don't manually assign current_mentorhelp
|
||||||
|
//msg is the title of the ticket: usually the ahelp text
|
||||||
|
/datum/mentor_help/New(msg, client/C)
|
||||||
|
//clean the input msg
|
||||||
|
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||||
|
if(!msg || !C || !C.mob)
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
|
||||||
|
id = ++ticket_counter
|
||||||
|
opened_at = world.time
|
||||||
|
|
||||||
|
name = msg
|
||||||
|
|
||||||
|
initiator = C
|
||||||
|
initiator_ckey = initiator.ckey
|
||||||
|
initiator_key_name = key_name(initiator, FALSE, TRUE)
|
||||||
|
if(initiator.current_mentorhelp) //This is a bug
|
||||||
|
log_debug("Ticket erroneously left open by code")
|
||||||
|
initiator.current_mentorhelp.AddInteraction("Ticket erroneously left open by code")
|
||||||
|
initiator.current_mentorhelp.Resolve()
|
||||||
|
initiator.current_mentorhelp = src
|
||||||
|
|
||||||
|
statclick = new(null, src)
|
||||||
|
_interactions = list()
|
||||||
|
|
||||||
|
log_admin("Mentorhelp: [key_name(C)] sent [msg]")
|
||||||
|
MessageNoRecipient(msg)
|
||||||
|
//show it to the person adminhelping too
|
||||||
|
to_chat(C, "<i><span class='mentor'>PM to-<b>Mentors</b>: [name]</span></i>")
|
||||||
|
|
||||||
|
GLOB.mhelp_tickets.active_tickets += src
|
||||||
|
|
||||||
|
/datum/mentor_help/Destroy()
|
||||||
|
RemoveActive()
|
||||||
|
GLOB.mhelp_tickets.closed_tickets -= src
|
||||||
|
GLOB.mhelp_tickets.resolved_tickets -= src
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/mentor_help/proc/AddInteraction(formatted_message)
|
||||||
|
_interactions += "[gameTimestamp()]: [formatted_message]"
|
||||||
|
|
||||||
|
//private
|
||||||
|
/datum/mentor_help/proc/ClosureLinks(ref_src)
|
||||||
|
if(!ref_src)
|
||||||
|
ref_src = "\ref[src]"
|
||||||
|
. = " (<A HREF='?_src_=mentorholder;mhelp=[ref_src];mhelp_action=resolve'>RSLVE</A>)"
|
||||||
|
|
||||||
|
//private
|
||||||
|
/datum/mentor_help/proc/LinkedReplyName(ref_src)
|
||||||
|
if(!ref_src)
|
||||||
|
ref_src = "\ref[src]"
|
||||||
|
return "<A HREF='?_src_=mentorholder;mhelp=[ref_src];mhelp_action=reply'>[initiator_ckey]</A>"
|
||||||
|
|
||||||
|
//private
|
||||||
|
/datum/mentor_help/proc/TicketHref(msg, ref_src, action = "ticket")
|
||||||
|
if(!ref_src)
|
||||||
|
ref_src = "\ref[src]"
|
||||||
|
return "<A HREF='?_src_=mentorholder;mhelp=[ref_src];mhelp_action=[action]'>[msg]</A>"
|
||||||
|
|
||||||
|
//message from the initiator without a target, all admins will see this
|
||||||
|
/datum/mentor_help/proc/MessageNoRecipient(msg)
|
||||||
|
var/ref_src = "\ref[src]"
|
||||||
|
var/chat_msg = "<span class='notice'>Ticket [TicketHref("#[id]", ref_src)]<b>: [LinkedReplyName(ref_src)]:</b> [msg]</span>"
|
||||||
|
AddInteraction("<font color='red'>[LinkedReplyName(ref_src)]: [msg]</font>")
|
||||||
|
for (var/client/C in GLOB.mentors)
|
||||||
|
if (C.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
|
||||||
|
C << 'sound/effects/mentorhelp.mp3'
|
||||||
|
for (var/client/C in GLOB.admins)
|
||||||
|
if (C.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
|
||||||
|
C << 'sound/effects/mentorhelp.mp3'
|
||||||
|
message_mentors(chat_msg)
|
||||||
|
|
||||||
|
//Reopen a closed ticket
|
||||||
|
/datum/mentor_help/proc/Reopen()
|
||||||
|
if(state == AHELP_ACTIVE)
|
||||||
|
to_chat(usr, "<span class='warning'>This ticket is already open.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(GLOB.mhelp_tickets.CKey2ActiveTicket(initiator_ckey))
|
||||||
|
to_chat(usr, "<span class='warning'>This user already has an active ticket, cannot reopen this one.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
statclick = new(null, src)
|
||||||
|
GLOB.mhelp_tickets.active_tickets += src
|
||||||
|
GLOB.mhelp_tickets.closed_tickets -= src
|
||||||
|
GLOB.mhelp_tickets.resolved_tickets -= src
|
||||||
|
switch(state)
|
||||||
|
if(AHELP_CLOSED)
|
||||||
|
feedback_dec("mhelp_close")
|
||||||
|
if(AHELP_RESOLVED)
|
||||||
|
feedback_dec("mhelp_resolve")
|
||||||
|
state = AHELP_ACTIVE
|
||||||
|
closed_at = null
|
||||||
|
if(initiator)
|
||||||
|
initiator.current_mentorhelp = src
|
||||||
|
|
||||||
|
AddInteraction("<font color='purple'>Reopened by [usr]</font>")
|
||||||
|
if(initiator)
|
||||||
|
to_chat(initiator, "<span class='filter_adminlog'><font color='purple'>Ticket [TicketHref("#[id]")] was reopened by [usr].</font></span>")
|
||||||
|
var/msg = "<span class='adminhelp'>Ticket [TicketHref("#[id]")] reopened by [usr].</span>"
|
||||||
|
message_mentors(msg)
|
||||||
|
log_admin(msg)
|
||||||
|
feedback_inc("mhelp_reopen")
|
||||||
|
TicketPanel() //can only be done from here, so refresh it
|
||||||
|
|
||||||
|
//private
|
||||||
|
/datum/mentor_help/proc/RemoveActive()
|
||||||
|
if(state != AHELP_ACTIVE)
|
||||||
|
return
|
||||||
|
closed_at = world.time
|
||||||
|
QDEL_NULL(statclick)
|
||||||
|
GLOB.mhelp_tickets.active_tickets -= src
|
||||||
|
if(initiator && initiator.current_mentorhelp == src)
|
||||||
|
initiator.current_mentorhelp = null
|
||||||
|
|
||||||
|
//Mark open ticket as resolved/legitimate, returns mentorhelp verb
|
||||||
|
/datum/mentor_help/proc/Resolve(silent = FALSE)
|
||||||
|
if(state != AHELP_ACTIVE)
|
||||||
|
return
|
||||||
|
RemoveActive()
|
||||||
|
state = AHELP_RESOLVED
|
||||||
|
GLOB.mhelp_tickets.ListInsert(src)
|
||||||
|
|
||||||
|
AddInteraction("<span class='filter_adminlog'><font color='green'>Resolved by [usr].</font></span>")
|
||||||
|
if(initiator)
|
||||||
|
to_chat(initiator, "<span class='filter_adminlog'><font color='green'>Ticket [TicketHref("#[id]")] was marked resolved by [usr].</font></span>")
|
||||||
|
if(!silent)
|
||||||
|
feedback_inc("mhelp_resolve")
|
||||||
|
var/msg = "Ticket [TicketHref("#[id]")] resolved by [usr]"
|
||||||
|
message_mentors(msg)
|
||||||
|
log_admin(msg)
|
||||||
|
|
||||||
|
//Show the ticket panel
|
||||||
|
/datum/mentor_help/proc/TicketPanel()
|
||||||
|
var/list/dat = list("<html><head><title>Ticket #[id]</title></head>")
|
||||||
|
var/ref_src = "\ref[src]"
|
||||||
|
dat += "<h4>Mentor Help Ticket #[id]: [LinkedReplyName(ref_src)]</h4>"
|
||||||
|
dat += "<b>State: "
|
||||||
|
switch(state)
|
||||||
|
if(AHELP_ACTIVE)
|
||||||
|
dat += "<font color='red'>OPEN</font>"
|
||||||
|
if(AHELP_RESOLVED)
|
||||||
|
dat += "<font color='green'>RESOLVED</font>"
|
||||||
|
if(AHELP_CLOSED)
|
||||||
|
dat += "CLOSED"
|
||||||
|
else
|
||||||
|
dat += "UNKNOWN"
|
||||||
|
dat += "</b>[GLOB.TAB][TicketHref("Refresh", ref_src)]"
|
||||||
|
if(state != AHELP_ACTIVE)
|
||||||
|
dat += "[GLOB.TAB][TicketHref("Reopen", ref_src, "reopen")]"
|
||||||
|
dat += "<br><br>Opened at: [gameTimestamp(wtime = opened_at)] (Approx [(world.time - opened_at) / 600] minutes ago)"
|
||||||
|
if(closed_at)
|
||||||
|
dat += "<br>Closed at: [gameTimestamp(wtime = closed_at)] (Approx [(world.time - closed_at) / 600] minutes ago)"
|
||||||
|
dat += "<br><br>"
|
||||||
|
if(initiator)
|
||||||
|
dat += "<b>Actions:</b> [FullMonty(ref_src)]<br>"
|
||||||
|
else
|
||||||
|
dat += "<b>DISCONNECTED</b>[GLOB.TAB][ClosureLinks(ref_src)]<br>"
|
||||||
|
dat += "<br><b>Log:</b><br><br>"
|
||||||
|
for(var/I in _interactions)
|
||||||
|
dat += "[I]<br>"
|
||||||
|
|
||||||
|
usr << browse(dat.Join(), "window=mhelp[id];size=620x480")
|
||||||
|
|
||||||
|
/datum/mentor_help/proc/FullMonty(ref_src)
|
||||||
|
if(!ref_src)
|
||||||
|
ref_src = "\ref[src]"
|
||||||
|
if(state == AHELP_ACTIVE)
|
||||||
|
. += ClosureLinks(ref_src)
|
||||||
|
|
||||||
|
//Forwarded action from admin/Topic OR mentor/Topic depending on which rank the caller has
|
||||||
|
/datum/mentor_help/proc/Action(action)
|
||||||
|
switch(action)
|
||||||
|
if("ticket")
|
||||||
|
TicketPanel()
|
||||||
|
if("reply")
|
||||||
|
usr.client.cmd_mhelp_reply(initiator)
|
||||||
|
if("resolve")
|
||||||
|
Resolve()
|
||||||
|
if("reopen")
|
||||||
|
Reopen()
|
||||||
|
|
||||||
|
//
|
||||||
|
// TICKET STATCLICK
|
||||||
|
//
|
||||||
|
|
||||||
|
/obj/effect/statclick/mhelp
|
||||||
|
var/datum/mentor_help/mhelp_datum
|
||||||
|
|
||||||
|
/obj/effect/statclick/mhelp/New(loc, datum/mentor_help/MH)
|
||||||
|
mhelp_datum = MH
|
||||||
|
..(loc)
|
||||||
|
|
||||||
|
/obj/effect/statclick/mhelp/update()
|
||||||
|
return ..(mhelp_datum.name)
|
||||||
|
|
||||||
|
/obj/effect/statclick/mhelp/Click()
|
||||||
|
mhelp_datum.TicketPanel()
|
||||||
|
|
||||||
|
/obj/effect/statclick/mhelp/Destroy()
|
||||||
|
mhelp_datum = null
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
//
|
||||||
|
// CLIENT PROCS
|
||||||
|
//
|
||||||
|
|
||||||
|
/client/verb/mentorhelp(msg as text)
|
||||||
|
set category = "Admin"
|
||||||
|
set name = "Mentorhelp"
|
||||||
|
|
||||||
|
if(say_disabled) //This is here to try to identify lag problems
|
||||||
|
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
//handle muting and automuting
|
||||||
|
if(prefs.muted & MUTE_ADMINHELP)
|
||||||
|
to_chat(src, "<span class='danger'>Error: Mentor-PM: You cannot send adminhelps (Muted).</span>")
|
||||||
|
return
|
||||||
|
if(handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
//remove out adminhelp verb temporarily to prevent spamming of admins.
|
||||||
|
src.verbs -= /client/verb/mentorhelp
|
||||||
|
spawn(600)
|
||||||
|
src.verbs += /client/verb/mentorhelp // 1 minute cool-down for mentorhelps
|
||||||
|
|
||||||
|
feedback_add_details("admin_verb","Mentorhelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||||
|
if(current_mentorhelp)
|
||||||
|
if(tgui_alert(usr, "You already have a ticket open. Is this for the same issue?","Duplicate?",list("Yes","No")) != "No")
|
||||||
|
if(current_mentorhelp)
|
||||||
|
log_admin("Mentorhelp: [key_name(src)] sent [msg]")
|
||||||
|
current_mentorhelp.MessageNoRecipient(msg)
|
||||||
|
to_chat(usr, "<span class='adminnotice'><span class='mentor_channel'>PM to-<b>Mentors</b>:</span> [msg]</span>")
|
||||||
|
return
|
||||||
|
else
|
||||||
|
to_chat(usr, "<span class='warning'>Ticket not found, creating new one...</span>")
|
||||||
|
else
|
||||||
|
current_mentorhelp.AddInteraction("[usr] opened a new ticket.")
|
||||||
|
current_mentorhelp.Resolve()
|
||||||
|
|
||||||
|
new /datum/mentor_help(msg, src, FALSE)
|
||||||
|
|
||||||
|
//admin proc
|
||||||
|
/client/proc/cmd_mentor_ticket_panel()
|
||||||
|
set name = "Show Mentor Ticket List"
|
||||||
|
set category = "Admin"
|
||||||
|
|
||||||
|
var/browse_to
|
||||||
|
|
||||||
|
switch(tgui_input_list(usr, "Display which ticket list?", "List Choice", list("Active Tickets", "Resolved Tickets")))
|
||||||
|
if("Active Tickets")
|
||||||
|
browse_to = AHELP_ACTIVE
|
||||||
|
if("Resolved Tickets")
|
||||||
|
browse_to = AHELP_RESOLVED
|
||||||
|
else
|
||||||
|
return
|
||||||
|
|
||||||
|
GLOB.mhelp_tickets.BrowseTickets(browse_to)
|
||||||
|
|
||||||
|
/proc/message_mentors(var/msg)
|
||||||
|
msg = "<span class='mentor_channel'><span class='prefix'>Mentor:</span> <span class=\"message\">[msg]</span></span>"
|
||||||
|
|
||||||
|
for(var/client/C in GLOB.mentors)
|
||||||
|
to_chat(C, msg)
|
||||||
|
for(var/client/C in GLOB.admins)
|
||||||
|
to_chat(C, msg)
|
||||||
@@ -90,6 +90,8 @@ body.inverted {
|
|||||||
.pm .other {color: #0000ff;}
|
.pm .other {color: #0000ff;}
|
||||||
|
|
||||||
/* Admin: Channels */
|
/* Admin: Channels */
|
||||||
|
.mentor {color: #ff9933;}
|
||||||
|
.mentor_channel {color: #ff9933; font-weight: bold;}
|
||||||
.mod_channel {color: #735638; font-weight: bold;}
|
.mod_channel {color: #735638; font-weight: bold;}
|
||||||
.mod_channel .admin {color: #b82e00; font-weight: bold;}
|
.mod_channel .admin {color: #b82e00; font-weight: bold;}
|
||||||
.admin_channel {color: #9611D4; font-weight: bold;}
|
.admin_channel {color: #9611D4; font-weight: bold;}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ em {font-style: normal;font-weight: bold;}
|
|||||||
.pm .other {color: #0000ff;}
|
.pm .other {color: #0000ff;}
|
||||||
|
|
||||||
/* Admin: Channels */
|
/* Admin: Channels */
|
||||||
|
.mentor_channel {color: #ff9933; font-weight: bold;}
|
||||||
|
.mentor {color: #ff9933;}
|
||||||
.mod_channel {color: #735638; font-weight: bold;}
|
.mod_channel {color: #735638; font-weight: bold;}
|
||||||
.mod_channel .admin {color: #b82e00; font-weight: bold;}
|
.mod_channel .admin {color: #b82e00; font-weight: bold;}
|
||||||
.admin_channel {color: #9611D4; font-weight: bold;}
|
.admin_channel {color: #9611D4; font-weight: bold;}
|
||||||
|
|||||||
BIN
sound/effects/mentorhelp.mp3
Normal file
BIN
sound/effects/mentorhelp.mp3
Normal file
Binary file not shown.
@@ -2787,6 +2787,8 @@
|
|||||||
#include "code\modules\media\media_tracks.dm"
|
#include "code\modules\media\media_tracks.dm"
|
||||||
#include "code\modules\media\mediamanager.dm"
|
#include "code\modules\media\mediamanager.dm"
|
||||||
#include "code\modules\media\walkpod.dm"
|
#include "code\modules\media\walkpod.dm"
|
||||||
|
#include "code\modules\mentor\mentor.dm"
|
||||||
|
#include "code\modules\mentor\mentorhelp.dm"
|
||||||
#include "code\modules\metric\activity.dm"
|
#include "code\modules\metric\activity.dm"
|
||||||
#include "code\modules\metric\count.dm"
|
#include "code\modules\metric\count.dm"
|
||||||
#include "code\modules\metric\department.dm"
|
#include "code\modules\metric\department.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user