diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm
index 87ce7e599ec..61bfd723241 100644
--- a/code/_globalvars/configuration.dm
+++ b/code/_globalvars/configuration.dm
@@ -8,9 +8,6 @@ var/changelog_hash = ""
var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 544)
var/aliens_allowed = 1
-var/ooc_allowed = 1
-var/dsay_allowed = 1
-var/dooc_allowed = 1
var/traitor_scaling = 1
//var/goonsay_allowed = 0
var/dna_ident = 1
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 6a607f00143..4347b373aff 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -10,6 +10,7 @@ var/list/clients = list() //list of all clients
var/list/admins = list() //list of all clients whom are admins
var/list/deadmins = list() //list of all clients who have used the de-admin verb.
var/list/directory = list() //list of all ckeys with associated client
+var/list/stealthminID = list() //reference list with IDs that store ckeys, for stealthmins
//Since it didn't really belong in any other category, I'm putting this here
//This is for procs to replace all the goddamn 'in world's that are chilling around the code
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 5f6f5c9978a..137d434eb04 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -164,6 +164,11 @@
var/disable_away_missions = 0 // disable away missions
var/autoconvert_notes = 0 //if all connecting player's notes should attempt to be converted to the database
+
+ var/ooc_allowed = 1
+ var/looc_allowed = 1
+ var/dooc_allowed = 1
+ var/dsay_allowed = 1
/datum/configuration/New()
var/list/L = subtypesof(/datum/game_mode)
@@ -341,6 +346,16 @@
if ("guest_ban")
guests_allowed = 0
+
+ if ("disable_ooc")
+ config.ooc_allowed = 0
+ config.looc_allowed = 0
+
+ if ("disable_dead_ooc")
+ config.dooc_allowed = 0
+
+ if ("disable_dsay")
+ config.dsay_allowed = 0
if ("usewhitelist")
config.usewhitelist = 1
diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm
index f7d8dc3d8c7..2d163186f41 100644
--- a/code/controllers/voting.dm
+++ b/code/controllers/voting.dm
@@ -59,9 +59,9 @@ datum/controller/vote
voting.Cut()
current_votes.Cut()
- if(auto_muted && !ooc_allowed)
+ if(auto_muted && !config.ooc_allowed)
auto_muted = 0
- ooc_allowed = !( ooc_allowed )
+ config.ooc_allowed = !( config.ooc_allowed )
world << "The OOC channel has been automatically enabled due to vote end."
log_admin("OOC was toggled automatically due to vote end.")
message_admins("OOC has been toggled on automatically.")
@@ -239,21 +239,21 @@ datum/controller/vote
if(mode == "gamemode" && going)
going = 0
world << "Round start has been delayed."
- if(mode == "crew_transfer" && ooc_allowed)
+ if(mode == "crew_transfer" && config.ooc_allowed)
auto_muted = 1
- ooc_allowed = !( ooc_allowed )
+ config.ooc_allowed = !( config.ooc_allowed )
world << "The OOC channel has been automatically disabled due to a crew transfer vote."
log_admin("OOC was toggled automatically due to crew_transfer vote.")
message_admins("OOC has been toggled off automatically.")
- if(mode == "gamemode" && ooc_allowed)
+ if(mode == "gamemode" && config.ooc_allowed)
auto_muted = 1
- ooc_allowed = !( ooc_allowed )
+ config.ooc_allowed = !( config.ooc_allowed )
world << "The OOC channel has been automatically disabled due to the gamemode vote."
log_admin("OOC was toggled automatically due to gamemode vote.")
message_admins("OOC has been toggled off automatically.")
- if(mode == "custom" && ooc_allowed)
+ if(mode == "custom" && config.ooc_allowed)
auto_muted = 1
- ooc_allowed = !( ooc_allowed )
+ config.ooc_allowed = !( config.ooc_allowed )
world << "The OOC channel has been automatically disabled due to a custom vote."
log_admin("OOC was toggled automatically due to custom vote.")
message_admins("OOC has been toggled off automatically.")
diff --git a/code/defines/procs/admin.dm b/code/defines/procs/admin.dm
index 8cce4b7e214..1824abaf6ae 100644
--- a/code/defines/procs/admin.dm
+++ b/code/defines/procs/admin.dm
@@ -21,12 +21,13 @@
. = ""
if(key)
- if(include_link && C)
- . += ""
-
if(C && C.holder && C.holder.fakekey && !include_name)
+ if(include_link)
+ . += ""
. += "Administrator"
else
+ if(include_link)
+ . += ""
. += key
if(include_link)
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index cd2c6f2854a..24be28454b3 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -5,32 +5,34 @@ var/global/moderator_ooc_colour = "#184880"
var/global/admin_ooc_colour = "#b82e00"
/client/verb/ooc(msg as text)
- set name = "OOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite
+ set name = "OOC"
set category = "OOC"
- if(!mob) return
+ if(!mob)
+ return
if(IsGuestKey(key))
- src << "Guests may not use OOC."
+ src << "Guests may not use OOC."
return
msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)))
- if(!msg) return
+ if(!msg)
+ return
if(!(prefs.toggles & CHAT_OOC))
- src << "\red You have OOC muted."
+ src << "You have OOC muted."
return
if(!check_rights(R_MOD,0))
- if(!ooc_allowed)
- src << "\red OOC is globally muted"
+ if(!config.ooc_allowed)
+ src << "OOC is globally muted."
return
- if(!dooc_allowed && (mob.stat == DEAD))
- usr << "\red OOC for dead mobs has been turned off."
+ if(!config.dooc_allowed && (mob.stat == DEAD))
+ usr << "OOC for dead mobs has been turned off."
return
if(prefs.muted & MUTE_OOC)
- src << "\red You cannot use OOC (muted)."
+ src << "You cannot use OOC (muted)."
return
- if(handle_spam_prevention(msg,MUTE_OOC))
+ if(handle_spam_prevention(msg, MUTE_OOC))
return
if(findtext(msg, "byond://"))
src << "Advertising other servers is not allowed."
@@ -71,14 +73,14 @@ var/global/admin_ooc_colour = "#b82e00"
C << "OOC: [display_name]: [msg]"
/proc/toggle_ooc()
- ooc_allowed = !( ooc_allowed )
- if (ooc_allowed)
+ config.ooc_allowed = ( !config.ooc_allowed )
+ if (config.ooc_allowed)
world << "The OOC channel has been globally enabled!"
else
- world << "The OOC channel has been globally disabled!"
-
+ world << "The OOC channel has been globally disabled!"
+
/proc/auto_toggle_ooc(var/on)
- if(config.auto_toggle_ooc_during_round && ooc_allowed != on)
+ if(config.auto_toggle_ooc_during_round && config.ooc_allowed != on)
toggle_ooc()
/client/proc/set_ooc(newColor as color)
@@ -137,31 +139,33 @@ var/global/admin_ooc_colour = "#b82e00"
feedback_add_details("admin_verb","ROC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/looc(msg as text)
- set name = "LOOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite
+ set name = "LOOC"
set desc = "Local OOC, seen only by those in view."
set category = "OOC"
- if(!mob) return
+ if(!mob)
+ return
if(IsGuestKey(key))
- src << "Guests may not use OOC."
+ src << "Guests may not use OOC."
return
msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)))
- if(!msg) return
+ if(!msg)
+ return
if(!(prefs.toggles & CHAT_LOOC))
- src << "\red You have LOOC muted."
+ src << "You have LOOC muted."
return
if(!check_rights(R_MOD,0))
- if(!ooc_allowed)
- src << "\red LOOC is globally muted"
+ if(!config.looc_allowed)
+ src << "LOOC is globally muted."
return
- if(!dooc_allowed && (mob.stat == DEAD))
- usr << "\red LOOC for dead mobs has been turned off."
+ if(!config.dooc_allowed && (mob.stat == DEAD))
+ usr << "LOOC for dead mobs has been turned off."
return
if(prefs.muted & MUTE_OOC)
- src << "\red You cannot use LOOC (muted)."
+ src << "You cannot use LOOC (muted)."
return
if(handle_spam_prevention(msg,MUTE_OOC))
return
@@ -172,39 +176,52 @@ var/global/admin_ooc_colour = "#b82e00"
return
log_ooc("(LOCAL) [mob.name]/[key] : [msg]")
- var/list/heard = get_mobs_in_view(7, src.mob)
- var/mob/S = src.mob
+
+ var/mob/source = mob.get_looc_source()
+ var/list/heard = get_mobs_in_view(7, source)
- var/display_name = S.key
- if(S.stat != DEAD)
- display_name = S.name
+ var/display_name = key
+ if(holder && holder.fakekey)
+ display_name = holder.fakekey
+ if(mob.stat != DEAD)
+ display_name = mob.name
- // Handle non-admins
- for(var/mob/M in heard)
- if(!M.client)
- continue
- var/client/C = M.client
- if(check_rights(R_MOD,0,M))
- continue //they are handled after that
+ for(var/client/target in clients)
+ if(target.prefs.toggles & CHAT_LOOC)
+ var/prefix = ""
+ var/admin_stuff = ""
+ var/send = 0
- if(C.prefs.toggles & CHAT_LOOC)
- if(holder)
- if(holder.fakekey)
- if(C.holder)
- display_name = "[holder.fakekey]/([src.key])"
- else
- display_name = holder.fakekey
- C << "LOOC: [display_name]: [msg]"
+ if(target in admins)
+ if(check_rights(R_MOD,0,target.mob))
+ admin_stuff += "/([key])"
+ if(target != src)
+ admin_stuff += "([admin_jump_link(mob, target.holder)])"
- // Now handle admins
- display_name = S.key
- if(S.stat != DEAD)
- display_name = "[S.name]/([S.key])"
+ if(target.mob in heard)
+ send = 1
+ if(isAI(target.mob))
+ prefix = " (Core)"
- for(var/client/C in admins)
- if(check_rights(R_MOD,0,C.mob))
- if(C.prefs.toggles & CHAT_LOOC)
- var/prefix = "(R)LOOC"
- if (C.mob in heard)
- prefix = "LOOC"
- C << "[prefix]: [display_name]: [msg]"
+ else if(isAI(target.mob)) // Special case
+ var/mob/living/silicon/ai/A = target.mob
+ if(A.eyeobj in hearers(7, source))
+ send = 1
+ prefix = " (Eye)"
+
+ if(!send && (target in admins))
+ if(check_rights(R_MOD,0,target.mob))
+ send = 1
+ prefix = "(R)"
+
+ if(send)
+ target << "LOOC[prefix]: [display_name][admin_stuff]: [msg]"
+
+/mob/proc/get_looc_source()
+ return src
+
+/mob/living/silicon/ai/get_looc_source()
+ if(eyeobj)
+ return eyeobj
+ return src
+
\ No newline at end of file
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index e2f080a7631..dc3f4884add 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -553,18 +553,40 @@ var/global/nologevent = 0
set category = "Server"
set desc="Globally Toggles OOC"
set name="Toggle OOC"
+
+ if(!check_rights(R_ADMIN))
+ return
+
toggle_ooc()
- log_admin("[key_name(usr)] toggled OOC.")
- message_admins("[key_name_admin(usr)] toggled OOC.", 1)
+ log_and_message_admins("toggled OOC.")
feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/datum/admins/proc/togglelooc()
+ set category = "Server"
+ set desc="Globally Toggles LOOC"
+ set name="Toggle LOOC"
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ config.looc_allowed = !(config.looc_allowed)
+ if (config.looc_allowed)
+ world << "The LOOC channel has been globally enabled!"
+ else
+ world << "The LOOC channel has been globally disabled!"
+ log_and_message_admins("toggled LOOC.")
+ feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggledsay()
set category = "Server"
set desc="Globally Toggles DSAY"
set name="Toggle DSAY"
- dsay_allowed = !( dsay_allowed )
- if (dsay_allowed)
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ config.dsay_allowed = !(config.dsay_allowed)
+ if (config.dsay_allowed)
world << "Deadchat has been globally enabled!"
else
world << "Deadchat has been globally disabled!"
@@ -574,11 +596,14 @@ var/global/nologevent = 0
/datum/admins/proc/toggleoocdead()
set category = "Server"
- set desc="Toggle dis bitch"
+ set desc="Toggle Dead OOC."
set name="Toggle Dead OOC"
- dooc_allowed = !( dooc_allowed )
- log_admin("[key_name(usr)] toggled OOC.")
+ if(!check_rights(R_ADMIN))
+ return
+
+ config.dooc_allowed = !( config.dooc_allowed )
+ log_admin("[key_name(usr)] toggled Dead OOC.")
message_admins("[key_name_admin(usr)] toggled Dead OOC.", 1)
feedback_add_details("admin_verb","TDOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 0164e814864..cf02ecef5c8 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -49,6 +49,7 @@ var/list/admin_verbs_admin = list(
/client/proc/toggle_hear_radio, /*toggles whether we hear the radio*/
/client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/
/datum/admins/proc/toggleooc, /*toggles ooc on/off for everyone*/
+ /datum/admins/proc/togglelooc, /*toggles looc on/off for everyone*/
/datum/admins/proc/toggleoocdead, /*toggles ooc on/off for everyone who is dead*/
/datum/admins/proc/toggledsay, /*toggles dsay on/off for everyone*/
/client/proc/game_panel, /*game panel, allows to change game-mode etc*/
@@ -347,6 +348,25 @@ var/list/admin_verbs_mentor = list(
holder.Secrets()
feedback_add_details("admin_verb","S") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
+
+/client/proc/findStealthKey(txt)
+ if(txt)
+ for(var/P in stealthminID)
+ if(stealthminID[P] == txt)
+ return P
+ txt = stealthminID[ckey]
+ return txt
+
+/client/proc/createStealthKey()
+ var/num = (rand(0,1000))
+ var/i = 0
+ while(i == 0)
+ i = 1
+ for(var/P in stealthminID)
+ if(num == stealthminID[P])
+ num++
+ i = 0
+ stealthminID["[ckey]"] = "@[num2text(num)]"
/client/proc/stealth()
set category = "Admin"
@@ -360,6 +380,7 @@ var/list/admin_verbs_mentor = list(
if(length(new_key) >= 26)
new_key = copytext(new_key, 1, 26)
holder.fakekey = new_key
+ createStealthKey()
log_admin("[key_name(usr)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]")
message_admins("[key_name_admin(usr)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]", 1)
feedback_add_details("admin_verb","SM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 0b244992381..06e9a389ba9 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -58,16 +58,26 @@
//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM.
//Fetching a message if needed. src is the sender and C is the target client
-/client/proc/cmd_admin_pm(var/client/C, var/msg, var/type="PM")
+/client/proc/cmd_admin_pm(whom, msg, type = "PM")
if(prefs.muted & MUTE_ADMINHELP)
src << "Error: Private-Message: You are unable to use PM-s (muted)."
return
- if(!istype(C,/client))
- if(holder) src << "Error: Private-Message: Client not found."
- else adminhelp(msg) //admin we are replying to left. adminhelp instead
+ var/client/C
+ if(istext(whom))
+ if(cmptext(copytext(whom,1,2),"@"))
+ whom = findStealthKey(whom)
+ C = directory[C]
+ else if(istype(whom,/client))
+ C = whom
+
+ if(!C)
+ if(holder)
+ src << "Error: Private-Message: Client not found."
+ else
+ adminhelp(msg) //admin we are replying to left. adminhelp instead
return
-
+
/*if(C && C.last_pm_recieved + config.simultaneous_pm_warning_timeout > world.time && holder)
//send a warning to admins, but have a delay popup for mods
if(holder.rights & R_ADMIN)
@@ -78,12 +88,15 @@
//get message text, limit it's length.and clean/escape html
if(!msg)
- msg = input(src,"Message:", "Private message to [C.key]") as text|null
+ msg = input(src,"Message:", "Private message to [key_name(C, 0, 0)]") as text|null
- if(!msg) return
+ if(!msg)
+ return
if(!C)
- if(holder) src << "Error: Admin-PM: Client not found."
- else adminhelp(msg) //admin we are replying to has vanished, adminhelp instead
+ if(holder)
+ src << "Error: Admin-PM: Client not found."
+ else
+ adminhelp(msg) //admin we are replying to has vanished, adminhelp instead
return
if (src.handle_spam_prevention(msg,MUTE_ADMINHELP))
@@ -92,7 +105,8 @@
//clean the message if it's not sent by a high-rank admin
if(!check_rights(R_SERVER|R_DEBUG,0))
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
- if(!msg) return
+ if(!msg)
+ return
var/recieve_color = "purple"
var/send_pm_type = " "
diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm
index a20af6d43d4..453e6d81f69 100644
--- a/code/modules/admin/verbs/deadsay.dm
+++ b/code/modules/admin/verbs/deadsay.dm
@@ -35,6 +35,9 @@
if (!msg)
return
- say_dead_direct("[stafftype] ([src.holder.fakekey ? src.holder.fakekey : src.key]) says, \"[msg]\"")
+ var/prefix = "[stafftype] ([src.key])"
+ if(holder.fakekey)
+ prefix = "Administrator"
+ say_dead_direct("[prefix] says, \"[msg]\"")
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index db4c78b055b..8f1f8c38ad1 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -93,7 +93,7 @@
return
if(!src.client.holder)
- if(!dsay_allowed)
+ if(!config.dsay_allowed)
src << "\red Deadchat is globally muted"
return
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 64b0118b46b..a65d31d1229 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -41,7 +41,7 @@
/mob/proc/say_dead(var/message)
if(!src.client.holder)
- if(!dsay_allowed)
+ if(!config.dsay_allowed)
src << "Deadchat is globally muted."
return
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 6cd6c266e5e..5de33855d51 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -14,6 +14,7 @@ em {font-style: normal; font-weight: bold;}
.prefix { font-weight: bold;}
.ooc { font-weight: bold;}
+.looc {color: #6699CC;}
.adminobserverooc {color: #0099cc; font-weight: bold;}
.adminooc {color: #b82e00; font-weight: bold;}
diff --git a/config/example/config.txt b/config/example/config.txt
index 28c664f3b6a..8612aafaf3c 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -291,4 +291,13 @@ PLAYER_REROUTE_CAP 0
#DISABLE_AWAY_MISSIONS
## Uncomment this out if you still use the old .sav file based notes system and haven't used the mass conversion proc
-#AUTOCONVERT_NOTES
\ No newline at end of file
+#AUTOCONVERT_NOTES
+
+## Uncomment to disable the OOC/LOOC channel by default.
+#DISABLE_OOC
+
+## Uncomment to disable the dead OOC channel by default.
+#DISABLE_DEAD_OOC
+
+## Uncomment to disable ghost chat by default.
+#DISABLE_DSAY
\ No newline at end of file