diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index d158a53effa4..487ef45bde4d 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -98,6 +98,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
/client/proc/cmd_admin_law_panel,
/client/proc/log_viewer_new,
/client/proc/player_ticket_history,
+ /client/proc/admin_lobby_chat, // NON-MODULE CHANGE
)
GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/ban_panel, /client/proc/stickybanpanel, /client/proc/library_control))
GLOBAL_PROTECT(admin_verbs_ban)
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 4f951025ba1c..670ae76ac6c5 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -417,4 +417,89 @@
SSticker.ready_report -= src // should be redundant but just in case.
return ..()
+/mob/dead/new_player/say(message, bubble_type, list/spans, sanitize, datum/language/language, ignore_spam, forced, filterproof, message_range, datum/saymode/saymode)
+ if(isnull(client) || client.interviewee)
+ return
+
+ client.lobby_chat(message)
+
+/// Lobby chat: An intermedium between OOC and IC chat, where players can talk to each other before joining the game / while the game sets up
+/client/proc/lobby_chat(message)
+ VALIDATE_CLIENT(src)
+
+ if(GLOB.say_disabled) //This is here to try to identify lag problems
+ to_chat(src, span_danger("Speech is currently admin-disabled."))
+ return
+ if(is_banned_from(ckey, "OOC"))
+ to_chat(src, span_danger("You have been banned from lobby chat."))
+ return
+
+ message = trim(sanitize(message), MAX_MESSAGE_LEN)
+ var/list/filter_result = is_ooc_filtered(message)
+ if (!CAN_BYPASS_FILTER(mob) && filter_result)
+ REPORT_CHAT_FILTER_TO_USER(src, filter_result)
+ log_filter("OOC", message, filter_result)
+ return
+ var/list/soft_filter_result = filter_result || is_soft_ooc_filtered(message)
+ if (soft_filter_result)
+ if(tgui_alert(src, "Your message contains \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". \"[soft_filter_result[CHAT_FILTER_INDEX_REASON]]\", Are you sure you want to say it?", "Soft Blocked Word", list("Yes", "No")) != "Yes")
+ return
+ message_admins("[ADMIN_LOOKUPFLW(src)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term. Message: \"[message]\"")
+ log_admin_private("[key_name(src)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term. Message: \"[message]\"")
+ if(!message || QDELETED(src))
+ return
+ mob.log_talk(message, LOG_OOC)
+ message = "[emoji_parse(message)]"
+
+ var/player_name = key
+ var/fake_key = holder?.fakekey
+ if(fake_key)
+ player_name = fake_key
+ else if(length(holder?.ranks))
+ player_name = "[span_tooltip(holder.rank_names(), "STAFF")] [key]"
+
+ if(prefs.hearted)
+ var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat)
+ player_name = "[sheet.icon_tag("emoji-heart")] [player_name]"
+ if(prefs.unlock_content && (prefs.toggles & MEMBER_PUBLIC))
+ player_name = "[icon2html('icons/ui_icons/chat/member_content.dmi', world, "blag")] [player_name]"
+
+ // relay lobby chat to all people in the lobby
+ // goes to info, so people who separate ooc can still see it in the main tab
+ for(var/mob/dead/new_player/recipient as anything in GLOB.new_player_list)
+ if(isnull(recipient.client)) // allegedly all new players are cliented, but who knows?
+ continue
+
+ var/visible_name = player_name
+ if(fake_key)
+ if(recipient == src || check_rights_for(recipient.client, R_STEALTH))
+ visible_name += " / ([key])"
+ else if(fake_key in recipient.client.prefs.ignoring)
+ continue
+
+ else if(key in recipient.client.prefs.ignoring)
+ continue
+
+ to_chat(recipient, span_nicegreen("[span_prefix("LOBBY:")] [visible_name]: [message]"), avoid_highlighting = (recipient == src), type = MESSAGE_TYPE_INFO)
+
+ // relay lobby chat to admins who aren't in the lobby, so they can monitor it
+ // spits to OOC instead of info, so as to not annoy admins who separate their chats out
+ for(var/client/admin as anything in GLOB.admins)
+ if(isnewplayer(admin.mob)) // already sees it
+ continue
+
+ var/visible_name = player_name
+ if(fake_key && (admin == src || check_rights_for(admin, R_STEALTH)))
+ visible_name += " / ([key])"
+
+ to_chat(admin, span_nicegreen("[span_prefix("LOBBY (RELAYED):")] [visible_name]: [message]"), type = MESSAGE_TYPE_OOC)
+
+/// Allows admins in game to speak to people in lobby chat
+/client/proc/admin_lobby_chat(msg as text)
+ set name = "Lobby Chat Relay"
+ set category = "OOC"
+ set desc = "Relay a message to the lobby chat from in game."
+
+ lobby_chat(msg)
+
#undef RESET_HUD_INTERVAL
diff --git a/maplestation_modules/code/modules/client/verbs/looc.dm b/maplestation_modules/code/modules/client/verbs/looc.dm
index be5a8f23febf..b2f3bebe937f 100644
--- a/maplestation_modules/code/modules/client/verbs/looc.dm
+++ b/maplestation_modules/code/modules/client/verbs/looc.dm
@@ -25,7 +25,7 @@ GLOBAL_VAR_INIT(looc_allowed, TRUE)
to_chat(src, span_danger("LOOC is globally muted."))
return
if(!GLOB.dooc_allowed && (mob.stat == DEAD))
- to_chat(src, span_danger("OOC / LOOC for dead mobs has been turned off."))
+ to_chat(src, span_danger("LOOC for dead mobs has been turned off."))
return
if(prefs.muted & MUTE_OOC)
to_chat(src, span_danger("You cannot use LOOC (muted)."))
@@ -36,10 +36,10 @@ GLOBAL_VAR_INIT(looc_allowed, TRUE)
// Really?
if(!SSticker.HasRoundStarted())
- to_chat(src, span_danger("The round hasn't started yet, dummy! Just use OOC."))
+ to_chat(src, span_danger("The round hasn't started yet!"))
return
- if(istype(mob, /mob/dead/new_player))
- to_chat(src, span_danger("You're not in game to broadcast LOOC anywhere! Use OOC."))
+ if(isnewplayer(mob))
+ to_chat(src, span_danger("You're not in game to broadcast LOOC anywhere!"))
return
// Check for people with OOC muted
@@ -49,14 +49,13 @@ GLOBAL_VAR_INIT(looc_allowed, TRUE)
// Check for people banned from OOC
if(is_banned_from(ckey, "OOC"))
- to_chat(src, span_danger("You have been banned from OOC / LOOC."))
+ to_chat(src, span_danger("You have been banned from LOOC."))
return
if(QDELETED(src))
return
- msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN)
-
+ msg = trim(sanitize(msg), MAX_MESSAGE_LEN)
if(!msg)
return