diff --git a/code/__DEFINES/bans.dm b/code/__DEFINES/bans.dm
new file mode 100644
index 00000000000..2b958e2ba1a
--- /dev/null
+++ b/code/__DEFINES/bans.dm
@@ -0,0 +1 @@
+#define BAN_OOC "OOC"
diff --git a/code/modules/client/verbs/looc.dm b/code/modules/client/verbs/looc.dm
index 872414c25d4..77e30e7a819 100644
--- a/code/modules/client/verbs/looc.dm
+++ b/code/modules/client/verbs/looc.dm
@@ -3,128 +3,108 @@
//GLOBAL_VAR_INIT(looc_allowed, 1) //commenting this out might break something but w/e, replaced by one in global config by nsv13
/client/verb/looc(msg as text)
- set name = "LOOC"
- set desc = "Local OOC, seen only by those in view."
- set category = "OOC"
-
- if(GLOB.say_disabled) //This is here to try to identify lag problems
- to_chat(usr, " Speech is currently admin-disabled.")
- return
-
- if(!mob) return
- if(!mob.ckey) return
-
- msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
- var/raw_msg = msg
-
- if(!msg)
- return
-
- if(!(prefs.chat_toggles & CHAT_LOOC)) //nsv13 - toggles -> chat_toggles, CHAT_OOC -> CHAT_LOOC
- to_chat(src, "You have LOOC muted.")
- return
-
- if(is_banned_from(mob.ckey, "OOC"))
- to_chat(src, "You have been banned from OOC and LOOC.")
- return
-
- if(!holder)
- if(!GLOB.looc_allowed) //nsv13 - ooc_allowed -> looc_allowed
- to_chat(src, "LOOC is globally muted.")
- return
- if(!GLOB.dooc_allowed && (mob.stat == DEAD))
- to_chat(usr, "LOOC for dead mobs has been turned off.")
- return
- if(prefs.muted & MUTE_LOOC) //nsv13 - MUTE_OOC -> MUTE_LOOC
- to_chat(src, "You cannot use LOOC (muted).")
- return
- if(handle_spam_prevention(msg,MUTE_LOOC)) //nsv13 - MUTE_OOC -> MUTE_LOOC
- return
- if(findtext(msg, "byond://"))
- to_chat(src, "Advertising other servers is not allowed.")
- log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]")
- return
- if(mob.stat)
- to_chat(src, "You cannot salt in LOOC while unconscious or dead.")
- return
- if(istype(mob, /mob/dead))
- to_chat(src, "You cannot use LOOC while ghosting.")
- return
-
- if(OOC_FILTER_CHECK(raw_msg))
- to_chat(src, "That message contained a word prohibited in OOC chat! Consider reviewing the server rules.\n\"[raw_msg]\"")
- return
-
- msg = emoji_parse(msg)
-
- mob.log_talk(raw_msg, LOG_OOC, tag="LOOC")
-
- var/list/heard = hearers(7, get_top_level_mob(src.mob))
-
+ set name = "LOOC"
+ set desc = "Local OOC, seen only by those in view."
+ set category = "OOC"
+
+ if(GLOB.say_disabled) //This is here to try to identify lag problems
+ to_chat(usr, " Speech is currently admin-disabled.")
+ return
+
+ if(!mob?.ckey)
+ return
+
+ msg = trim(sanitize(msg), MAX_MESSAGE_LEN)
+ if(!length(msg))
+ return
+
+ var/raw_msg = msg
+
+ if(!(prefs.chat_toggles & CHAT_LOOC)) //nsv13 - toggles -> chat_toggles, CHAT_OOC -> CHAT_LOOC
+ to_chat(src, "You have LOOC muted.")
+ return
+
+ if(is_banned_from(mob.ckey, BAN_OOC))
+ to_chat(src, "You have been banned from OOC and LOOC.")
+ return
+
+ if(!holder)
+ if(!GLOB.looc_allowed) //nsv13 - ooc_allowed -> looc_allowed
+ to_chat(src, "LOOC is globally muted.")
+ return
+ if(!GLOB.dooc_allowed && (mob.stat == DEAD))
+ to_chat(usr, "LOOC for dead mobs has been turned off.")
+ return
+ if(prefs.muted & MUTE_LOOC) //nsv13 - MUTE_OOC -> MUTE_LOOC
+ to_chat(src, "You cannot use LOOC (muted).")
+ return
+ if(handle_spam_prevention(msg, MUTE_LOOC)) //nsv13 - MUTE_OOC -> MUTE_LOOC
+ return
+ if(findtext(msg, "byond://"))
+ to_chat(src, "Advertising other servers is not allowed.")
+ log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]")
+ return
+ if(mob.stat)
+ to_chat(src, "You cannot salt in LOOC while unconscious or dead.")
+ return
+ if(isdead(mob))
+ to_chat(src, "You cannot use LOOC while ghosting.")
+ return
+
+ if(OOC_FILTER_CHECK(raw_msg))
+ to_chat(src, "That message contained a word prohibited in OOC chat! Consider reviewing the server rules.\n\"[raw_msg]\"")
+ return
+
+ msg = emoji_parse(msg)
+
+ mob.log_talk(raw_msg, LOG_OOC, tag="LOOC")
+
+ // Search everything in the view for anything that might be a mob, or contain a mob.
+ var/list/client/targets = list()
+ var/list/turf/in_view = list()
//NSV13 - AI QoL - Start
//so the ai can post looc text
- if(istype(mob, /mob/living/silicon/ai))
- var/mob/living/silicon/ai/ai = mob
- heard = hearers(7, get_top_level_mob(ai.eyeobj))
- //so the ai can see looc text
- for(var/mob/living/silicon/ai/ai as anything in GLOB.ai_list)
- if(ai.client && !(ai in heard) && (ai.eyeobj in heard))
- heard += ai
+ if(istype(mob, /mob/living/silicon/ai))
+ var/mob/living/silicon/ai/ai = mob
+ for(var/turf/viewed_turf in view(get_turf(ai.eyeobj)))
+ in_view[viewed_turf] = TRUE
+ else
+ for(var/turf/viewed_turf in view(get_turf(mob)))
+ in_view[viewed_turf] = TRUE
//NSV13 - AI QoL - Stop
-
- for(var/mob/M as() in heard)
- if(!M.client)
- continue
- var/client/C = M.client
- if (C in GLOB.admins)
- continue //they are handled after that
-
- if (isobserver(M))
- continue //Also handled later.
-
- if(C.prefs.chat_toggles & CHAT_LOOC) //nsv13 - toggles -> chat_toggles, CHAT_OOC -> CHAT_LOOC
-// var/display_name = src.key
-// if(holder)
-// if(holder.fakekey)
-// if(C.holder)
-// display_name = "[holder.fakekey]/([src.key])"
-// else
-// display_name = holder.fakekey
- to_chat(C,"LOOC: [src.mob.name]: [msg]")
-
- for(var/client/C in GLOB.admins)
- if(C.prefs.chat_toggles & CHAT_LOOC) //nsv13 - toggles -> chat_toggles, CHAT_OOC -> CHAT_LOOC
- var/prefix = "(R)LOOC"
- if (C.mob in heard)
- prefix = "LOOC"
- to_chat(C,"[ADMIN_FLW(usr)][prefix]: [src.key]/[src.mob.name]: [msg]")
+ for(var/client/client in GLOB.clients)
+ if(!client.mob || !(client.prefs.chat_toggles & CHAT_LOOC) || (client in GLOB.admins)) //nsv13 - toggles -> chat_toggles, CHAT_OOC -> CHAT_LOOC
+ continue
+ //NSV13 - LOOC AI Stuff - Start
+ if(istype(client.mob, /mob/living/silicon/ai))
+ var/mob/living/silicon/ai/ai = client.mob
+ if(in_view[get_turf(ai.eyeobj)])
+ targets |= client
+ to_chat(client, "LOOC: [mob.name]: [msg]", avoid_highlighting = (client == src))
+ else if(in_view[get_turf(client.mob)]) //NSV13 - LOOC AI Stuff - Stop
+ targets |= client
+ to_chat(client, "LOOC: [mob.name]: [msg]", avoid_highlighting = (client == src))
+
+ for(var/client/client in GLOB.admins)
+ if(!(client.prefs.chat_toggles & CHAT_LOOC)) //nsv13 - toggles -> chat_toggles, CHAT_OOC -> CHAT_LOOC
+ continue
+ var/prefix = "[(client in targets) ? "" : "(R)"]LOOC"
+ to_chat(client, "[prefix]: [ADMIN_LOOKUPFLW(mob)]: [msg]", avoid_highlighting = (client == src))
/proc/toggle_looc(toggle = null) //nsv13 - adds a toggle for looc
- if(toggle != null) //if we're specifically en/disabling looc
- if(toggle != GLOB.looc_allowed)
- GLOB.looc_allowed = toggle
- else
- return
- else //otherwise just toggle it
- GLOB.looc_allowed = !GLOB.looc_allowed
+ if(toggle != null) //if we're specifically en/disabling looc
+ if(toggle != GLOB.looc_allowed)
+ GLOB.looc_allowed = toggle
+ else
+ return
+ else //otherwise just toggle it
+ GLOB.looc_allowed = !GLOB.looc_allowed
/proc/log_looc(text)
- if (CONFIG_GET(flag/log_ooc))
- WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]LOOC: [text]")
+ if (CONFIG_GET(flag/log_ooc))
+ WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]LOOC: [text]")
////////////////////FLAVOUR TEXT NSV13////////////////////
/mob
var/flavour_text = ""
//NSV13 - flavour text - Don't think this thing actually does anything - END
-
-/mob/proc/get_top_level_mob()
- if(istype(src.loc,/mob)&&src.loc!=src)
- var/mob/M=src.loc
- return M.get_top_level_mob()
- return src
-
-/proc/get_top_level_mob(var/mob/S)
- if(istype(S.loc,/mob)&&S.loc!=S)
- var/mob/M=S.loc
- return M.get_top_level_mob()
- return S
diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm
index 955902e9e40..a956339c4a1 100644
--- a/code/modules/client/verbs/ooc.dm
+++ b/code/modules/client/verbs/ooc.dm
@@ -25,7 +25,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
if(prefs.muted & MUTE_OOC)
to_chat(src, "You cannot use OOC (muted).")
return
- if(is_banned_from(ckey, "OOC"))
+ if(is_banned_from(ckey, BAN_OOC))
to_chat(src, "You have been banned from OOC.")
return
if(QDELETED(src))
diff --git a/nsv13.dme b/nsv13.dme
index 3a98b52c0a9..f4565a41f55 100644
--- a/nsv13.dme
+++ b/nsv13.dme
@@ -38,6 +38,7 @@
#include "code\__DEFINES\atmospherics.dm"
#include "code\__DEFINES\atom_hud.dm"
#include "code\__DEFINES\balloon_alert.dm"
+#include "code\__DEFINES\bans.dm"
#include "code\__DEFINES\bitfields.dm"
#include "code\__DEFINES\bodyparts.dm"
#include "code\__DEFINES\bot_defines.dm"