diff --git a/code/controllers/subsystem/tickets/mentor_tickets.dm b/code/controllers/subsystem/tickets/mentor_tickets.dm
index af4ea2e914d..dc9a54d6fbc 100644
--- a/code/controllers/subsystem/tickets/mentor_tickets.dm
+++ b/code/controllers/subsystem/tickets/mentor_tickets.dm
@@ -10,19 +10,25 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets
ticket_system_name = "Mentor Tickets"
ticket_name = "Mentor Ticket"
span_class = "mentorhelp"
+ anchor_link_extra = ";is_mhelp=1"
+ ticket_help_type = "Mentorhelp"
+ ticket_help_span = "mentorhelp"
other_ticket_name = "Admin"
other_ticket_permission = R_ADMIN
close_rights = R_MENTOR | R_ADMIN
rights_needed = R_MENTOR | R_ADMIN | R_MOD
/datum/controller/subsystem/tickets/mentor_tickets/Initialize()
+ . = ..()
close_messages = list("- [ticket_name] Closed -",
"Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.",
"Your [ticket_name] has now been closed.")
- return ..()
-/datum/controller/subsystem/tickets/mentor_tickets/message_staff(msg)
- message_mentorTicket(msg)
+/datum/controller/subsystem/tickets/mentor_tickets/message_staff(msg, prefix_type = NONE, important = FALSE)
+ message_mentorTicket(msg, important)
/datum/controller/subsystem/tickets/mentor_tickets/create_other_system_ticket(datum/ticket/T)
- SStickets.newTicket(T.clientName, T.content, T.title)
+ SStickets.newTicket(T.clientName, T.content, T.raw_title)
+
+/datum/controller/subsystem/tickets/mentor_tickets/autoRespond(N)
+ return
diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm
index 64f91e96b6c..93455111595 100644
--- a/code/controllers/subsystem/tickets/tickets.dm
+++ b/code/controllers/subsystem/tickets/tickets.dm
@@ -10,6 +10,9 @@
#define TICKET_RESOLVED 3
#define TICKET_STALE 4
+#define TICKET_STAFF_MESSAGE_ADMIN_CHANNEL 1
+#define TICKET_STAFF_MESSAGE_PREFIX 2
+
SUBSYSTEM_DEF(tickets)
name = "Admin Tickets"
init_order = INIT_ORDER_TICKETS
@@ -24,6 +27,11 @@ SUBSYSTEM_DEF(tickets)
var/close_rights = R_ADMIN
var/rights_needed = R_ADMIN | R_MOD
+ /// Text that will be added to the anchor link
+ var/anchor_link_extra = ""
+
+ var/ticket_help_type = "Adminhelp"
+ var/ticket_help_span = "adminhelp"
/// The name of the other ticket type to convert to
var/other_ticket_name = "Mentor"
/// Which permission to look for when seeing if there is staff available for the other ticket type
@@ -76,22 +84,55 @@ SUBSYSTEM_DEF(tickets)
var/datum/ticket/T = i
resolveTicket(T.ticketNum)
+/**
+ * Will either make a new ticket using the given text or will add the text to an existing ticket.
+ * Staff will get a message
+ * Arguments:
+ * C - The client who requests help
+ * text - The text the client send
+ */
+/datum/controller/subsystem/tickets/proc/newHelpRequest(client/C, text)
+ var/ticketNum // Holder for the ticket number
+ var/datum/ticket/T
+ // Get the open ticket assigned to the client and add a response. If no open tickets then make a new one
+ if((T = checkForOpenTicket(C)))
+ ticketNum = T.ticketNum
+ T.addResponse(C, text)
+ T.setCooldownPeriod()
+ to_chat(C.mob, "Your [ticket_name] #[ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.")
+ var/url_message = makeUrlMessage(C, text, ticketNum)
+ message_staff(url_message, NONE, TRUE)
+ else
+ newTicket(C, text, text)
+
+/**
+ * Will add the URLs usable by staff to the message and return it
+ * Arguments:
+ * C - The client who send the message
+ * msg - The raw message
+ * ticketNum - Which ticket number the ticket has
+ */
+/datum/controller/subsystem/tickets/proc/makeUrlMessage(client/C, msg, ticketNum)
+ var/finalised_msg = "[ticket_help_type]: [key_name(C, TRUE, ticket_help_type)] "
+ finalised_msg += "([ADMIN_QUE(C.mob,"?")]) ([ADMIN_PP(C.mob,"PP")]) ([ADMIN_VV(C.mob,"VV")]) ([ADMIN_TP(C.mob,"TP")]) ([ADMIN_SM(C.mob,"SM")]) "
+ finalised_msg += "([admin_jump_link(C.mob)]) (TICKET) "
+ finalised_msg += "[isAI(C.mob) ? "(CL)" : ""] (TAKE) "
+ finalised_msg += "(RESOLVE) (AUTO) "
+ finalised_msg += "(CONVERT) : [msg]"
+ return finalised_msg
+
//Open a new ticket and populate details then add to the list of open tickets
/datum/controller/subsystem/tickets/proc/newTicket(client/C, passedContent, title)
if(!C || !passedContent)
return
- //Check if the user has an open ticket already within the cooldown period, if so we don't create a new one and re-set the cooldown period
- var/datum/ticket/existingTicket = checkForOpenTicket(C)
- if(existingTicket)
- existingTicket.setCooldownPeriod()
- to_chat(C.mob, "Your [ticket_name] #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.")
- return
-
if(!title)
title = passedContent
- var/datum/ticket/T = new(title, passedContent, getTicketCounterAndInc())
+ var/new_ticket_num = getTicketCounterAndInc()
+ var/url_title = makeUrlMessage(C, title, new_ticket_num)
+
+ var/datum/ticket/T = new(url_title, title, passedContent, new_ticket_num)
allTickets += T
T.clientName = C
T.locationSent = C.mob.loc.name
@@ -102,6 +143,8 @@ SUBSYSTEM_DEF(tickets)
var/ticket_open_sound = sound('sound/effects/adminticketopen.ogg')
SEND_SOUND(C, ticket_open_sound)
+ message_staff(url_title, NONE, TRUE)
+
//Set ticket state with key N to open
/datum/controller/subsystem/tickets/proc/openTicket(N)
var/datum/ticket/T = allTickets[N]
@@ -146,7 +189,7 @@ SUBSYSTEM_DEF(tickets)
create_other_system_ticket(T)
/datum/controller/subsystem/tickets/proc/create_other_system_ticket(datum/ticket/T)
- SSmentor_tickets.newTicket(T.clientName, T.content, T.title)
+ SSmentor_tickets.newTicket(T.clientName, T.content, T.raw_title)
/datum/controller/subsystem/tickets/proc/autoRespond(N)
if(!check_rights(rights_needed))
@@ -247,6 +290,7 @@ SUBSYSTEM_DEF(tickets)
var/clientName // Client which opened the ticket
var/timeOpened // Time the ticket was opened
var/title //The initial message with links
+ var/raw_title // The title without URLs added
var/list/content // content of the staff help
var/lastStaffResponse // Last staff member who responded
var/lastResponseTime // When the staff last responded
@@ -257,8 +301,9 @@ SUBSYSTEM_DEF(tickets)
var/ticketCooldown // Cooldown before allowing the user to open another ticket.
var/client/staffAssigned // Staff member who has assigned themselves to this ticket
-/datum/ticket/New(tit, cont, num)
+/datum/ticket/New(tit, raw_tit, cont, num)
title = tit
+ raw_title = raw_tit
content = list()
content += cont
timeOpened = worldtime2text()
@@ -437,9 +482,21 @@ UI STUFF
to_chat(target, text)
return TRUE
-//Sends a message to the designated staff
-/datum/controller/subsystem/tickets/proc/message_staff(var/msg, var/alt = FALSE)
- message_adminTicket(msg, alt)
+/**
+ * Sends a message to the designated staff
+ * Arguments:
+ * msg - The message being send
+ * alt - If an alternative prefix should be used or not. Defaults to TICKET_STAFF_MESSAGE_PREFIX
+ * important - If the message is important. If TRUE it will ignore the CHAT_NO_TICKETLOGS preferences,
+ send a sound and flash the window. Defaults to FALSE
+ */
+/datum/controller/subsystem/tickets/proc/message_staff(msg, prefix_type = TICKET_STAFF_MESSAGE_PREFIX, important = FALSE)
+ switch(prefix_type)
+ if(TICKET_STAFF_MESSAGE_ADMIN_CHANNEL)
+ msg = "ADMIN TICKET: [msg]"
+ if(TICKET_STAFF_MESSAGE_PREFIX)
+ msg = "ADMIN TICKET: [msg]"
+ message_adminTicket(msg, important)
/datum/controller/subsystem/tickets/Topic(href, href_list)
@@ -521,7 +578,7 @@ UI STUFF
if(span_class == "mentorhelp")
message_staff("[usr.client] / ([usr]) has taken [ticket_name] number [index]")
else
- message_staff("[usr.client] / ([usr]) has taken [ticket_name] number [index]", TRUE)
+ message_staff("[usr.client] / ([usr]) has taken [ticket_name] number [index]", TICKET_STAFF_MESSAGE_ADMIN_CHANNEL)
to_chat_safe(returnClient(index), "Your [ticket_name] is being handled by [usr.client].")
/datum/controller/subsystem/tickets/proc/unassignTicket(index)
@@ -532,4 +589,7 @@ UI STUFF
if(span_class == "mentorhelp")
message_staff("[usr.client] / ([usr]) has unassigned [ticket_name] number [index]")
else
- message_staff("[usr.client] / ([usr]) has unassigned [ticket_name] number [index]", TRUE)
+ message_staff("[usr.client] / ([usr]) has unassigned [ticket_name] number [index]", TICKET_STAFF_MESSAGE_ADMIN_CHANNEL)
+
+#undef TICKET_STAFF_MESSAGE_ADMIN_CHANNEL
+#undef TICKET_STAFF_MESSAGE_PREFIX
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 0cb6a9701de..db3aca115a7 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -20,22 +20,39 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(C.prefs.atklog <= loglevel)
to_chat(C, msg)
-
-/proc/message_adminTicket(var/msg, var/alt = FALSE)
- if(alt)
- msg = "ADMIN TICKET: [msg]"
- else
- msg = "ADMIN TICKET: [msg]"
+/**
+ * Sends a message to the staff able to see admin tickets
+ * Arguments:
+ * msg - The message being send
+ * important - If the message is important. If TRUE it will ignore the CHAT_NO_TICKETLOGS preferences,
+ send a sound and flash the window. Defaults to FALSE
+ */
+/proc/message_adminTicket(msg, important = FALSE)
for(var/client/C in GLOB.admins)
if(R_ADMIN & C.holder.rights)
- if(C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS))
+ if(important || (C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS)))
to_chat(C, msg)
+ if(important)
+ if(C.prefs?.sound & SOUND_ADMINHELP)
+ SEND_SOUND(C, 'sound/effects/adminhelp.ogg')
+ window_flash(C)
-/proc/message_mentorTicket(var/msg)
+/**
+ * Sends a message to the staff able to see mentor tickets
+ * Arguments:
+ * msg - The message being send
+ * important - If the message is important. If TRUE it will ignore the CHAT_NO_TICKETLOGS preferences,
+ send a sound and flash the window. Defaults to FALSE
+ */
+/proc/message_mentorTicket(msg, important = FALSE)
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN | R_MENTOR | R_MOD, 0, C.mob))
- if(C.prefs && !(C.prefs.toggles & CHAT_NO_MENTORTICKETLOGS))
+ if(important || (C.prefs && !(C.prefs.toggles & CHAT_NO_MENTORTICKETLOGS)))
to_chat(C, msg)
+ if(important)
+ if(C.prefs?.sound & SOUND_MENTORHELP)
+ SEND_SOUND(C, 'sound/effects/adminhelp.ogg')
+ window_flash(C)
/proc/admin_ban_mobsearch(var/mob/M, var/ckey_to_find, var/mob/admin_to_notify)
if(!M || !M.ckey)
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index ecc60464949..f4ebc1370df 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -26,17 +26,16 @@
message_admins("[key_name_admin(usr)] rejected [key_name_admin(C.mob)]'s admin help")
log_admin("[key_name(usr)] rejected [key_name(C.mob)]'s admin help")
- if(href_list["openadminticket"])
- if(!check_rights(R_ADMIN))
- return
- var/ticketID = text2num(href_list["openadminticket"])
- SStickets.showDetailUI(usr, ticketID)
-
- if(href_list["openmentorticket"])
- if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
- return
- var/ticketID = text2num(href_list["openmentorticket"])
- SSmentor_tickets.showDetailUI(usr, ticketID)
+ if(href_list["openticket"])
+ var/ticketID = text2num(href_list["openticket"])
+ if(!href_list["is_mhelp"])
+ if(!check_rights(R_ADMIN))
+ return
+ SStickets.showDetailUI(usr, ticketID)
+ else
+ if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
+ return
+ SSmentor_tickets.showDetailUI(usr, ticketID)
if(href_list["stickyban"])
stickyban(href_list["stickyban"],href_list)
@@ -1666,6 +1665,9 @@
SStickets.resolveTicket(index)
else if(href_list["autorespond"])
+ if(href_list["is_mhelp"])
+ to_chat(usr, "Auto responses are not yet available for mentor helps.")
+ return
var/index = text2num(href_list["autorespond"])
if(!check_rights(R_ADMIN|R_MOD))
return
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 761f89ed04a..4289df8ffbc 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -29,64 +29,12 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","mo
msg = sanitize_simple(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg) return
- var/original_msg = msg
+ if(selected_type == "Mentorhelp")
+ SSmentor_tickets.newHelpRequest(src, msg)
+ else
+ SStickets.newHelpRequest(src, msg)
- //explode the input msg into a list
- var/list/msglist = splittext(msg, " ")
-
- //generate keywords lookup
- var/list/surnames = list()
- var/list/forenames = list()
- var/list/ckeys = list()
- for(var/mob/M in GLOB.mob_list)
- var/list/indexing = list(M.real_name, M.name)
- if(M.mind) indexing += M.mind.name
-
- for(var/string in indexing)
- var/list/L = splittext(string, " ")
- var/surname_found = 0
- //surnames
- for(var/i=L.len, i>=1, i--)
- var/word = ckey(L[i])
- if(word)
- surnames[word] = M
- surname_found = i
- break
- //forenames
- for(var/i=1, i[original_word] "
- continue
- msg += "[original_word] "
-
- if(!mob) return //this doesn't happen
-
- //send this msg to all admins
+ //See how many staff are on
var/admin_number_afk = 0
var/list/mentorholders = list()
var/list/modholders = list()
@@ -103,65 +51,19 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","mo
if(check_rights(R_MENTOR, 0, X.mob))
mentorholders += X
continue
- var/ticketNum // Holder for the ticket number
- var/prunedmsg ="[src]: [msg]" // Message without links
- var/datum/ticket/T
- var/isMhelp = selected_type == "Mentorhelp"
- var/span
- if(isMhelp)
- span = ""
- if(SSmentor_tickets.checkForOpenTicket(src)) // If user already has an open ticket
- T = SSmentor_tickets.checkForOpenTicket(src)
- else
- ticketNum = SSmentor_tickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
- else //Ahelp
- span = ""
- if(SStickets.checkForOpenTicket(src)) // If user already has an open ticket
- T = SStickets.checkForOpenTicket(src) // Make T equal to the ticket they have open
- else
- ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
-
- if(T)
- ticketNum = T.ticketNum // ticketNum is the number of their ticket.
- T.addResponse(src, msg)
-
- var/finalised_msg = "[span][selected_type]: [key_name(src, TRUE, selected_type)] "
- finalised_msg += "([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_TP(mob,"TP")]) ([ADMIN_SM(mob,"SM")]) "
- finalised_msg += "([admin_jump_link(mob)]) (TICKET) "
- finalised_msg += "[ai_found ? "(CL)" : ""] (TAKE) "
- finalised_msg += "(RESOLVE) [isMhelp ? "" : "(AUTO)"] "
- finalised_msg += "(CONVERT) : [span][msg]"
-
- if(isMhelp)
- //Open a new adminticket and inform the user.
- SSmentor_tickets.newTicket(src, prunedmsg, finalised_msg)
- for(var/client/X in mentorholders + modholders + adminholders)
- if(X.prefs.sound & SOUND_MENTORHELP)
- SEND_SOUND(X, 'sound/effects/adminhelp.ogg')
- to_chat(X, finalised_msg)
- else //Ahelp
- //Open a new adminticket and inform the user.
- SStickets.newTicket(src, prunedmsg, finalised_msg)
- for(var/client/X in modholders + adminholders)
- if(X.prefs.sound & SOUND_ADMINHELP)
- SEND_SOUND(X, 'sound/effects/adminhelp.ogg')
- window_flash(X)
- to_chat(X, finalised_msg)
-
-
//show it to the person adminhelping too
- to_chat(src, "[selected_type]: [original_msg]")
+ to_chat(src, "[selected_type]: [msg]")
var/admin_number_present = adminholders.len - admin_number_afk
- log_admin("[selected_type]: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins.")
+ log_admin("[selected_type]: [key_name(src)]: [msg] - heard by [admin_number_present] non-AFK admins.")
if(admin_number_present <= 0)
if(!admin_number_afk)
- send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!No admins online!!")
+ send2adminirc("[selected_type] from [key_name(src)]: [msg] - !!No admins online!!")
else
- send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!All admins AFK ([admin_number_afk])!!")
+ send2adminirc("[selected_type] from [key_name(src)]: [msg] - !!All admins AFK ([admin_number_afk])!!")
else
- send2adminirc("[selected_type] from [key_name(src)]: [original_msg]")
+ send2adminirc("[selected_type] from [key_name(src)]: [msg]")
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return