Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/game/world.dm
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ GLOBAL_VAR(restart_counter)
SetupLogs()

load_admins(initial = TRUE)
load_mentors() // MASSMETA ADDITION (mentors)

load_poll_data()

Expand Down
4 changes: 4 additions & 0 deletions code/modules/admin/verbs/adminhelp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
Retitle()
if("reject")
Reject()
// MASSMETA ADDITION START (mentors)
if("mhelp")
MHelpThis()
// MASSMETA ADDITION END
if("reply")
usr.client.cmd_ahelp_reply(initiator)
if("icissue")
Expand Down
1 change: 1 addition & 0 deletions modular_meta/_defines/_main_modular_defines_include.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
#include "re_hooch_heals_assistants.dm"
#include "justice_mecha.dm"
#include "techweb_nodes.dm"
#include "mentors.dm"
3 changes: 3 additions & 0 deletions modular_meta/_defines/mentors.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#define COMSIG_KB_ADMIN_MSAY_DOWN "keybinding_mentor_msay_down"

#define REQUEST_MENTORHELP "request_mentorhelp"
33 changes: 33 additions & 0 deletions modular_meta/features/mentors/code/ahelp_reject.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/datum/admin_help/ClosureLinks(ref_src)
. = ..()
. += " (<A HREF='?_src_=holder;[HrefToken(TRUE)];ahelp=[ref_src];ahelp_action=mhelp'>MHELP</A>)"

/**
* We're overwriting /datum/admin_help/proc/Action(action)
* This is to add the "Mhelp" button to the admin_help's Action
*/

/datum/admin_help/Action(action)
. = ..()
switch(action)
if("mhelp")
MHelpThis()

/datum/admin_help/proc/MHelpThis(key_name = key_name_admin(usr))
if(state != AHELP_ACTIVE)
return

if(initiator)
initiator.giveadminhelpverb()

SEND_SOUND(initiator, sound('sound/effects/adminhelp.ogg'))

to_chat(initiator, "<font color='red' size='4'><b>- MentorHelp Question! -</b></font>")
to_chat(initiator, "<font color='red'>This question is about <b>game mechanics</b>, so should be asked in <b>Mentorhelp</b> instead. To do so, use the <b>Mentorhelp</b> verb under the <b>Mentor<b> tab on the upper right of your screen.</font>")

SSblackbox.record_feedback("tally", "ahelp_stats", 1, "mhelp this")
var/msg = "Ticket [TicketHref("#[id]")] told to mentorhelp by [key_name]"
message_admins(msg)
log_admin_private(msg)
AddInteraction("Told to mentorhelp by [key_name].")
Close(silent = TRUE)
24 changes: 24 additions & 0 deletions modular_meta/features/mentors/code/follow.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/client/proc/mentor_follow(mob/living/followed_guy)
if(!is_mentor())
return
if(isnull(followed_guy))
return
if(!ismob(usr))
return
mentor_datum.following = followed_guy
usr.reset_perspective(followed_guy)
add_verb(src, /client/proc/mentor_unfollow)
to_chat(GLOB.admins, span_adminooc("<span class='prefix'>MENTOR:</span> <EM>[key_name(usr)]</EM> is now following <EM>[key_name(followed_guy)]</span>"))
to_chat(usr, span_info("Click the \"Stop Following\" button in the Mentor tab to stop following [key_name(followed_guy)]."))
log_mentor("[key_name(usr)] began following [key_name(followed_guy)]")

/client/proc/mentor_unfollow()
set category = "Mentor"
set name = "Stop Following"
set desc = "Stop following the followed."

remove_verb(src, /client/proc/mentor_unfollow)
usr.reset_perspective()
to_chat(GLOB.admins, span_adminooc("<span class='prefix'>MENTOR:</span> <EM>[key_name(usr)]</EM> is no longer following <EM>[key_name(mentor_datum.following)]</span>"))
log_mentor("[key_name(usr)] stopped following [key_name(mentor_datum.following)]")
mentor_datum.following = null
107 changes: 107 additions & 0 deletions modular_meta/features/mentors/code/mentor.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
GLOBAL_LIST_EMPTY(mentor_datums)
GLOBAL_PROTECT(mentor_datums)

GLOBAL_VAR_INIT(mentor_href_token, GenerateToken())
GLOBAL_PROTECT(mentor_href_token)

/datum/mentors
var/name = "someone's mentor datum"
/// The Mentor's Client
var/client/owner
/// the Mentor's Ckey
var/target
/// href token for Mentor commands, uses the same token used by Admins.
var/href_token
///The mob currently being followed with mfollow.
var/mob/following
/// Are we a Contributor?
var/is_contributor = FALSE
///List of all contributors for special MSAY text.
var/static/list/contributor_list = world.file2list("[global.config.directory]/contributors.txt")

/datum/mentors/New(ckey)
if(!ckey)
QDEL_IN(src, 0)
throw EXCEPTION("Mentor datum created without a ckey")
return
link_mentor_datum(ckey)

/datum/mentors/proc/link_mentor_datum(ckey)
target = ckey(ckey)
name = "[ckey]'s mentor datum"
href_token = GenerateToken()
GLOB.mentor_datums[target] = src
/// Set the owner var and load commands
owner = GLOB.directory[ckey]
if(owner)
owner.mentor_datum = src
owner.add_mentor_verbs()
GLOB.mentors += owner
if(ckey in contributor_list)
is_contributor = TRUE

/proc/RawMentorHrefToken(forceGlobal = FALSE)
var/tok = GLOB.mentor_href_token
if(!forceGlobal && usr)
var/client/all_clients = usr.client
to_chat(world, all_clients)
to_chat(world, usr)
if(!all_clients)
CRASH("No client for HrefToken()!")
var/datum/mentors/holder = all_clients.mentor_datum
if(holder)
tok = holder.href_token
return tok

/proc/MentorHrefToken(forceGlobal = FALSE)
return "mentor_token=[RawMentorHrefToken(forceGlobal)]"

///Loads all mentors from the mentors.txt file, setting admins as mentors as well.
/proc/load_mentors()
GLOB.mentor_datums.Cut()
for(var/client/mentor_clients in GLOB.mentors)
mentor_clients.remove_mentor_verbs()
mentor_clients.mentor_datum = null
GLOB.mentors.Cut()
var/list/lines = world.file2list("[global.config.directory]/mentors.txt")
for(var/line in lines)
if(!length(line))
continue
if(findtextEx(line, "#", 1, 2))
continue
new /datum/mentors(line)
for(var/client/admin in GLOB.admins)
//not a mentor, let's add them.
if(!GLOB.mentor_datums[admin.ckey])
new /datum/mentors(admin.ckey)

ADMIN_VERB(reload_mentors, R_ADMIN, "Reload Mentors", "Reload all mentors", "Mentor")
if(!user)
return

var/confirm = tgui_alert(usr, "Are you sure you want to reload all mentors?", "Confirm", list("Yes", "No"))
if(confirm != "Yes")
return

load_mentors()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Reload All Mentors") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc!
message_admins("[key_name_admin(usr)] manually reloaded mentors")

ADMIN_VERB(add_mentor, R_PERMISSIONS, "Add Mentor", "Add a new mentor", "Mentor" )
if(!user)
return

var/path = "[global.config.directory]/mentors.txt"
var/list/lines = world.file2list(path)
var/ckey = input("Enter ckey.", "Ckey") as text|null

if(ckey)
if(ckey in lines)
return
if(!GLOB.mentor_datums[ckey])
new /datum/mentors(ckey)
var/F = file(path)
WRITE_FILE(F, ckey)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Add a new mentor")
message_admins("[key_name_admin(usr)] has made [ckey] a mentor.")
log_admin("[key_name(usr)] has made [ckey] a mentor.")
36 changes: 36 additions & 0 deletions modular_meta/features/mentors/code/mentor_clientprocs.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/client
///If this is set, this person is a Mentor.
var/datum/mentors/mentor_datum

/client/New()
. = ..()
mentor_datum_set()

// Overwrites /client/Topic to return for mentor client procs
/client/Topic(href, href_list, hsrc)
//Replying to a mentorhelp
if(href_list["mentor_msg"])
cmd_mentor_pm(href_list["mentor_msg"], null)
return TRUE
//Following someone through a mentorhelp.
if(href_list["mentor_follow"])
var/mob/living/followed_guy = locate(href_list["mentor_follow"])
if(istype(followed_guy))
mentor_follow(followed_guy)
return TRUE
return ..()

///Sets the person to a mentor datum, linking if it exists, otherwise we'll create a new one if it's an admin.
///Anyone that isn't set to be a mentor will get nothing from this.
/client/proc/mentor_datum_set()
mentor_datum = GLOB.mentor_datums[ckey]
if(mentor_datum)
mentor_datum.link_mentor_datum(ckey)
else if(holder)
new /datum/mentors(ckey)

///Returns whether or not this client is a Mentor (Or Admin, cause they are also Mentors).
/client/proc/is_mentor()
if(mentor_datum || holder)
return TRUE
return FALSE
1 change: 1 addition & 0 deletions modular_meta/features/mentors/code/mentor_config.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/datum/config_entry/string/headofpseudostaff
11 changes: 11 additions & 0 deletions modular_meta/features/mentors/code/mentor_globalvars.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
GLOBAL_LIST_EMPTY(mentorlog)
GLOBAL_PROTECT(mentorlog)
GLOBAL_LIST_EMPTY(mentors)
GLOBAL_PROTECT(mentors)

GLOBAL_PROTECT(mentor_verbs)

GLOBAL_LIST_INIT(mentor_verbs, list(
/client/proc/cmd_mentor_say,
/client/proc/mentor_requests,
))
20 changes: 20 additions & 0 deletions modular_meta/features/mentors/code/mentor_keybinds.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/datum/keybinding/mentor
category = CATEGORY_ADMIN
weight = WEIGHT_ADMIN

/datum/keybinding/mentor/can_use(client/user)
return user.mentor_datum ? TRUE : FALSE

/datum/keybinding/mentor/mentor_say
hotkey_keys = list("F4")
name = "mentor_say"
full_name = "Mentor say"
description = "Talk with fellow mentors and admins."
keybind_signal = COMSIG_KB_ADMIN_MSAY_DOWN

/datum/keybinding/mentor/mentor_say/down(client/user)
. = ..()
if(.)
return
user.get_mentor_say()
return TRUE
11 changes: 11 additions & 0 deletions modular_meta/features/mentors/code/mentor_logging.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#define LOG_CATEGORY_MENTOR "mentor"

/proc/log_mentor(text, list/data)
GLOB.mentorlog.Add(text)
logger.Log(LOG_CATEGORY_MENTOR, text, data)
logger.Log(LOG_CATEGORY_COMPAT_GAME, "MENTOR: [text]")

/datum/log_category/mentorhelp
category = LOG_CATEGORY_MENTOR
master_category = /datum/log_category/admin
config_flag = /datum/config_entry/flag/log_admin
90 changes: 90 additions & 0 deletions modular_meta/features/mentors/code/mentor_manager.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/// Verb for opening the requests manager panel
/client/proc/mentor_requests()
set name = "Mentor Manager"
set desc = "Open the mentor manager panel to view all requests during this round"
set category = "Mentor"

SSblackbox.record_feedback("tally", "mentor_verb", 1, "Mentor Manager") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
GLOB.mentor_requests.ui_interact(usr)

GLOBAL_DATUM_INIT(mentor_requests, /datum/request_manager/mentor, new)

/datum/request_manager/mentor/ui_state(mob/user)
return GLOB.mentor_state

/datum/request_manager/mentor/pray(client/C, message, is_chaplain)
return

/datum/request_manager/mentor/message_centcom(client/C, message)
return

/datum/request_manager/mentor/message_syndicate(client/C, message)
return

/datum/request_manager/mentor/nuke_request(client/C, message)
return

/datum/request_manager/mentor/fax_request(client/requester, message, additional_info)
return

/datum/request_manager/mentor/music_request(client/requester, message)
return

/datum/request_manager/mentor/proc/mentorhelp(client/requester, message)
var/sanitizied_message = copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)
request_for_client(requester, REQUEST_MENTORHELP, sanitizied_message)

/datum/request_manager/mentor/ui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "RequestManagerMentor")
ui.open()

/datum/request_manager/mentor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
// Only admins should be sending actions
var/client/mentor_client = usr.client
if(!mentor_client || !mentor_client.is_mentor())
to_chat(mentor_client, "You are not allowed to be using this mentor-only proc. Please report it.", confidential = TRUE)
return

// Get the request this relates to
var/id = params["id"] != null ? text2num(params["id"]) : null
if (!id)
to_chat(mentor_client, "Failed to find a request ID in your action, please report this.", confidential = TRUE)
CRASH("Received an action without a request ID, this shouldn't happen!")
var/datum/request/request = !id ? null : requests_by_id[id]
if(isnull(request))
to_chat(mentor_client, "Failed to find a request to reply to, please report this.", confidential = TRUE)
return

switch(action)
if ("reply")
var/mob/M = request.owner?.mob
mentor_client.cmd_mentor_pm(M)
return TRUE
if ("follow")
var/mob/M = request.owner?.mob
mentor_client.mentor_follow(M)
return TRUE
return ..()

/datum/request_manager/mentor/ui_data(mob/user)
. = list(
"requests" = list(),
)
for (var/ckey in requests)
for (var/datum/request/request as anything in requests[ckey])
if(request.req_type != REQUEST_MENTORHELP)
continue
var/list/data = list(
"id" = request.id,
"req_type" = request.req_type,
"owner" = request.owner ? "[REF(request.owner)]" : null,
"owner_ckey" = request.owner_ckey,
"owner_name" = request.owner_name,
"message" = request.message,
"additional_info" = request.additional_information,
"timestamp" = request.timestamp,
"timestamp_str" = round_timestamp(wtime = request.timestamp)
)
.["requests"] += list(data)
12 changes: 12 additions & 0 deletions modular_meta/features/mentors/code/mentor_state.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* tgui state: mentor_state
*
* Checks that the user is a mentor, end-of-story.
*/

GLOBAL_DATUM_INIT(mentor_state, /datum/ui_state/mentor_state, new)

/datum/ui_state/mentor_state/can_use_topic(src_object, mob/user)
if(user.client.is_mentor())
return UI_INTERACTIVE
return UI_CLOSE
Loading
Loading