diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm
index 951a96558ca..5e93eb4ceec 100644
--- a/code/controllers/subsystem/tickets/tickets.dm
+++ b/code/controllers/subsystem/tickets/tickets.dm
@@ -94,6 +94,8 @@ SUBSYSTEM_DEF(tickets)
//Inform the user that they have opened a ticket
to_chat(C, "You have opened [ticket_name] number #[(getTicketCounter() - 1)]! Please be patient and we will help you soon!")
+ var/ticket_open_sound = sound('sound/effects/adminticketopen.ogg')
+ SEND_SOUND(C, ticket_open_sound)
//Set ticket state with key N to open
/datum/controller/subsystem/tickets/proc/openTicket(N)
@@ -111,7 +113,43 @@ SUBSYSTEM_DEF(tickets)
message_staff("[usr.client] / ([usr]) resolved [ticket_name] number [N]")
to_chat_safe(returnClient(N), "Your [ticket_name] has now been resolved.")
return TRUE
+
+/datum/controller/subsystem/tickets/proc/autoRespond(N)
+ var/datum/ticket/T = allTickets[N]
+ var/client/C = usr.client
+ if((T.staffAssigned && T.staffAssigned != C) || (T.lastStaffResponse && T.lastStaffResponse != C) || T.ticketState != TICKET_OPEN) //if someone took this ticket, is it the same admin who is autoresponding? if so, then skip the warning
+ if(alert(usr, "[T.ticketState == TICKET_OPEN ? "This ticket is already marked as closed or resolved" : "Another admin appears to already be handling this."] Are you sure you want to continue?", "Confirmation", "Yes", "No") != "Yes")
+ return
+ T.assignStaff(C)
+
+ //try to keep this list where more common things are at the top yeah? thx
+ var/response_phrases = list("Cancel" = "Cancel",
+ "Thanks" = "Thanks, have a Paradise day!",
+ "Already Resolved" = "The problem has been resolved already.",
+ "Mentorhelp" = "Please redirect your question to Mentorhelp, as they are better experienced with these types of questions.",
+ "Clear Cache" = "To fix a blank screen, please leave the game and clear your byond cache. To clear your Byond Cache, there is a Settings icon in the top right of the launcher. After you click that, go into the Games tab and hit the Clear Cache button. If the issue persists a few minutes after rejoining and doing this please adminhelp again and state you cleared your cache." ,
+ "IC Issue" = "This is an In Character (IC) issue and will not be handled by admins. You could speak to Security, Internal Affairs, a Departmental Head, Nanotrasen Representetive, or any other relevant authority currently on station.",
+ "Appeal on the Forums" = "Appealing a ban must occur on the forums. Privately messaging, or adminhelping about your ban will not resolve it. To appeal your ban, please head to [config.banappeals]"
+ )
+
+ var/sorted_responses = list()
+ for(var/key in response_phrases) //build a new list based on the short descriptive keys of the master list
+ sorted_responses += key
+
+ var/message_key = input("Select an autoresponse. This will mark the ticket as resolved.", "Autoresponse") as anything in sorted_responses
+
+ switch(message_key)
+ if("Cancel")
+ T.staffAssigned = initial(T.staffAssigned) //if they cancel we dont need to hold this ticket anymore
+ return
+ else
+ var/msg_sound = sound('sound/effects/adminhelp.ogg')
+ SEND_SOUND(returnClient(N), msg_sound)
+ to_chat(returnClient(N), "[key_name_hidden(C)] is autoresponding with: [response_phrases[message_key]]")//for this we want the full value of whatever key this is to tell the player
+ message_staff("[C] has auto responded to [T.clientName]\'s adminhelp with: [message_key] ") //we want to use the named keys for this which is why we do response_phrases[message_key]
+ resolveTicket(N)
+ log_game("[C] has auto responded to [T.clientName]\'s adminhelp with: [response_phrases[message_key]]")
//Set ticket state with key N to closed
/datum/controller/subsystem/tickets/proc/closeTicket(N)
var/datum/ticket/T = allTickets[N]
@@ -407,6 +445,11 @@ UI STUFF
takeTicket(indexNum)
showDetailUI(usr, indexNum)
+ if(href_list["autorespond"])
+ var/indexNum = text2num(href_list["autorespond"])
+ takeTicket(indexNum)
+ autoRespond(indexNum)
+
if(href_list["resolveall"])
if(ticket_system_name == "Mentor Tickets")
usr.client.resolveAllMentorTickets()
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 1bd103d95b2..2875c16c137 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1569,6 +1569,12 @@
else //Ahelp
SStickets.resolveTicket(index)
+ else if(href_list["autorespond"])
+ var/index = text2num(href_list["autorespond"])
+ if(!check_rights(R_ADMIN|R_MOD))
+ return
+ SStickets.autoRespond(index)
+
else if(href_list["cult_nextobj"])
if(alert(usr, "Validate the current Cult objective and unlock the next one?", "Cult Cheat Code", "Yes", "No") != "Yes")
return
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index b64b8cd56f5..8bd891f4c29 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -125,7 +125,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
ticketNum = T.ticketNum // ticketNum is the number of their ticket.
T.addResponse(src, msg)
- msg = "[span][selected_type]: [key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_TP(mob,"TP")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (TICKET) [ai_found ? "(CL)" : ""] (TAKE) (RESOLVE) : [span][msg]"
+ msg = "[span][selected_type]: [key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_TP(mob,"TP")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (TICKET) [ai_found ? "(CL)" : ""] (TAKE) [isMhelp ? "" : "(AUTO)"] : [span][msg]"
if(isMhelp)
//Open a new adminticket and inform the user.
SSmentor_tickets.newTicket(src, prunedmsg, msg)
diff --git a/goon/browserassets/css/browserOutput-dark.css b/goon/browserassets/css/browserOutput-dark.css
index 426493dfc88..76a2bde4532 100644
--- a/goon/browserassets/css/browserOutput-dark.css
+++ b/goon/browserassets/css/browserOutput-dark.css
@@ -413,3 +413,5 @@ h1.alert, h2.alert {color: #FFF;}
/* ADMIN TICKETS */
.adminticket {color: #3daf21; font-weight: bold}
+
+.adminticketalt {color: #ccb847; font-weight: bold}
diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css
index 07ae914de62..ce604cc5cac 100644
--- a/goon/browserassets/css/browserOutput.css
+++ b/goon/browserassets/css/browserOutput.css
@@ -409,4 +409,6 @@ h1.alert, h2.alert {color: #000000;}
/* ADMIN TICKETS */
-.adminticket {color: #3daf21; font-weight: bold}
+.adminticket {color: #3e7336; font-weight: bold}
+
+.adminticketalt {color: #014c8a; font-weight: bold}
diff --git a/sound/effects/adminhelp.ogg b/sound/effects/adminhelp.ogg
index 704c0fd6d20..12e58c95807 100644
Binary files a/sound/effects/adminhelp.ogg and b/sound/effects/adminhelp.ogg differ
diff --git a/sound/effects/adminhelplegacy.ogg b/sound/effects/adminhelplegacy.ogg
new file mode 100644
index 00000000000..704c0fd6d20
Binary files /dev/null and b/sound/effects/adminhelplegacy.ogg differ
diff --git a/sound/effects/adminticketopen.ogg b/sound/effects/adminticketopen.ogg
new file mode 100644
index 00000000000..82e0729d881
Binary files /dev/null and b/sound/effects/adminticketopen.ogg differ