diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index 050ab7c76f4..c397560ef5d 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -107,7 +107,17 @@
log_ooc("(LOCAL) [mob.name]/[key] : [msg]")
var/mob/source = src.mob
- var/list/heard = get_mobs_in_view(7, get_turf(source))
+ var/list/messageturfs = list()//List of turfs we broadcast to.
+ var/list/messagemobs = list()//List of living mobs nearby who can hear it
+
+ for (var/turf in range(world.view, get_turf(source)))
+ messageturfs += turf
+
+ for(var/mob/M in player_list)
+ if (!M.client)
+ continue
+ if(get_turf(M) in messageturfs)
+ messagemobs += M
var/display_name = source.key
if(holder && holder.fakekey)
@@ -130,7 +140,7 @@
admin_stuff += "/([source.key])"
if(target != source.client)
admin_stuff += "(JMP)"
- if(target.mob in heard)
+ if(target.mob in messagemobs)
prefix = ""
- if((target.mob in heard) || display_remote)
+ if((target.mob in messagemobs) || display_remote)
target << "" + create_text_tag("looc", "LOOC:", target) + " [prefix][display_name][admin_stuff]: [msg]"
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 5645773ea0b..aae74f63b44 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -24,71 +24,8 @@
if (message)
log_emote("[name]/[key] : [message]")
- var/list/seeing_obj = list() //For objs that need to see emotes. You can use see_emote(), which is based off of hear_talk()
+ send_emote(message, m_type)
- //Hearing gasp and such every five seconds is not good emotes were not global for a reason.
- // Maybe some people are okay with that.
-
- for(var/mob/M in player_list)
- if (!M.client)
- continue //skip monkeys and leavers
- if (istype(M, /mob/new_player))
- continue
- if(findtext(message," snores.")) //Because we have so many sleeping people.
- break
- if(M.stat == 2 && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
- M.show_message(message)
-
- for(var/I in view(world.view, get_turf(usr))) //get_turf is needed to stop weirdness with x-ray.
- if(istype(I, /mob/))
- var/mob/M = I
- for(var/obj/O in M.contents)
- seeing_obj |= O
- else if(istype(I, /obj/))
- var/obj/O = I
- seeing_obj |= O
-
- // Type 1 (Visual) emotes are sent to anyone in view of the item
- if (m_type & 1)
- //for (var/mob/O in viewers(src, null))
- for (var/mob/O in viewers(get_turf(src), null)) //This may break people with x-ray being able to see emotes across walls,
- //but this saves many headaches down the road, involving mechs and pAIs.
- //x-ray is so rare these days anyways.
-
- if(O.status_flags & PASSEMOTES)
-
- for(var/obj/item/weapon/holder/H in O.contents)
- H.show_message(message, m_type)
-
- for(var/mob/living/M in O.contents)
- M.show_message(message, m_type)
-
- O.show_message(message, m_type)
-
- for(var/obj/O in seeing_obj)
- spawn(0)
- if(O) //It's possible that it could be deleted in the meantime.
- O.see_emote(src, message, 1)
-
- // Type 2 (Audible) emotes are sent to anyone in hear range
- // of the *LOCATION* -- this is important for AIs/pAIs to be heard
- else if (m_type & 2)
- for (var/mob/O in hearers(get_turf(src), null))
-
- if(O.status_flags & PASSEMOTES)
-
- for(var/obj/item/weapon/holder/H in O.contents)
- H.show_message(message, m_type)
-
- for(var/mob/living/M in O.contents)
- M.show_message(message, m_type)
-
- O.show_message(message, m_type)
-
- for(var/obj/O in seeing_obj)
- spawn(0)
- if(O) //It's possible that it could be deleted in the meantime.
- O.see_emote(src, message, 2)
/mob/proc/emote_dead(var/message)
@@ -115,3 +52,36 @@
if(input)
log_emote("Ghost/[src.key] : [input]")
say_dead_direct(input, src)
+
+
+//This is a central proc that all emotes are run through. This handles sending the messages to living mobs
+/mob/proc/send_emote(var/message, var/type)
+ var/list/messageturfs = list()//List of turfs we broadcast to.
+ var/list/messagemobs = list()//List of living mobs nearby who can hear it, and distant ghosts who've chosen to hear it
+ var/list/messagemobs_neardead = list()//List of nearby ghosts who can hear it. Those that qualify ONLY go in this list
+ for (var/turf in view(world.view, get_turf(src)))
+ messageturfs += turf
+
+ for(var/mob/M in player_list)
+ if (!M.client)
+ continue
+ if(get_turf(M) in messageturfs)
+ if (istype(M, /mob/dead/observer))
+ messagemobs_neardead += M
+ continue
+ else if (istype(M, /mob/living) && !(type == 2 && (sdisabilities & DEAF || ear_deaf)))
+ messagemobs += M
+ else if(src.client)
+ if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTSIGHT))
+ messagemobs += M
+ continue
+
+ for (var/mob/N in messagemobs)
+ N.show_message(message, type)
+
+ message = "[message]"
+
+ for (var/mob/O in messagemobs_neardead)
+ O.show_message(message, type)
+
+
diff --git a/code/modules/mob/living/carbon/alien/emote.dm b/code/modules/mob/living/carbon/alien/emote.dm
index fd29d52298d..d8d4311c7a7 100644
--- a/code/modules/mob/living/carbon/alien/emote.dm
+++ b/code/modules/mob/living/carbon/alien/emote.dm
@@ -117,12 +117,5 @@
src << text("Invalid Emote: []", act)
if ((message && src.stat == 0))
log_emote("[name]/[key] : [message]")
- if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(703)
- else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(746)
+ send_emote(message, m_type)
return
diff --git a/code/modules/mob/living/carbon/brain/emote.dm b/code/modules/mob/living/carbon/brain/emote.dm
index 7e25c3be96f..818af164161 100644
--- a/code/modules/mob/living/carbon/brain/emote.dm
+++ b/code/modules/mob/living/carbon/brain/emote.dm
@@ -65,16 +65,4 @@
if (message)
log_emote("[name]/[key] : [message]")
- for(var/mob/M in dead_mob_list)
- if (!M.client || istype(M, /mob/new_player))
- continue //skip monkeys, leavers, and new_players
- if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
- M.show_message(message)
-
-
- if (m_type & 1)
- for (var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- else if (m_type & 2)
- for (var/mob/O in hearers(src.loc, null))
- O.show_message(message, m_type)
+ send_emote(message, m_type)
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 42ae4e86913..2236de619e3 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -571,19 +571,7 @@ wink, yawn, swish, sway/wag, fastsway/qwag, stopsway/swag"}
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
- for(var/mob/M in dead_mob_list)
- if(!M.client || istype(M, /mob/new_player))
- continue //skip monkeys, leavers and new players
- if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
- M.show_message(message)
-
-
- if (m_type & 1)
- for (var/mob/O in get_mobs_in_view(world.view,src))
- O.show_message(message, m_type)
- else if (m_type & 2)
- for (var/mob/O in (hearers(src.loc, null) | get_mobs_in_view(world.view,src)))
- O.show_message(message, m_type)
+ send_emote(message, m_type)
/mob/living/carbon/human/verb/pose()
diff --git a/code/modules/mob/living/carbon/metroid/emote.dm b/code/modules/mob/living/carbon/metroid/emote.dm
index e342c253983..4d78f1485d6 100644
--- a/code/modules/mob/living/carbon/metroid/emote.dm
+++ b/code/modules/mob/living/carbon/metroid/emote.dm
@@ -88,12 +88,7 @@
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
if ((message && src.stat == 0))
- if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
+ send_emote(message, m_type)
if(updateicon)
regenerate_icons()
return
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index d423f86ea25..cca2cbb7f83 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -263,7 +263,7 @@ proc/get_radio_key_from_channel(var/channel)
for(var/mob/M in player_list)
- if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
+ if(src.client && M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
listening |= M
continue
if(M.loc && M.locs[1] in hearturfs)
diff --git a/code/modules/mob/living/silicon/pai/emote.dm b/code/modules/mob/living/silicon/pai/emote.dm
index 7cecb30b636..3be0581c59b 100644
--- a/code/modules/mob/living/silicon/pai/emote.dm
+++ b/code/modules/mob/living/silicon/pai/emote.dm
@@ -91,10 +91,5 @@
src << "\blue Unusable emote '[act]'. Say *help for a list."
if ((message && src.stat == 0))
- if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
+ send_emote(message, m_type)
return
diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm
index 6fb40df0a81..3cdf49e178d 100644
--- a/code/modules/mob/living/silicon/robot/emote.dm
+++ b/code/modules/mob/living/silicon/robot/emote.dm
@@ -209,10 +209,5 @@
src << "\blue Unusable emote '[act]'. Say *help for a list."
if ((message && src.stat == 0))
- if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
+ send_emote(message, m_type)
return
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 978320d7c24..a9e1449cdbc 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -97,7 +97,18 @@
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
/mob/visible_message(var/message, var/self_message, var/blind_message)
- for(var/mob/M in viewers(src))
+ var/list/messageturfs = list()//List of turfs we broadcast to.
+ var/list/messagemobs = list()//List of living mobs nearby who can hear it, and distant ghosts who've chosen to hear it
+ for (var/turf in view(world.view, get_turf(src)))
+ messageturfs += turf
+
+ for(var/mob/M in player_list)
+ if (!M.client)
+ continue
+ if(get_turf(M) in messageturfs)
+ messagemobs += M
+
+ for(var/mob/M in messagemobs)
if(self_message && M==src)
M.show_message(self_message, 1, blind_message, 2)
else if(M.see_invisible < invisibility) // Cannot view the invisible, but you can hear it.
@@ -113,6 +124,7 @@
// message is the message output to anyone who can see e.g. "[src] does something!"
// self_message (optional) is what the src mob sees e.g. "You do something!"
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
+//This is obsolete now
/mob/proc/contained_visible_message(var/atom/broadcaster, var/message, var/self_message, var/blind_message)
var/self_served = 0
for(var/mob/M in viewers(broadcaster))
@@ -129,14 +141,28 @@
src.show_message(self_message, 1, blind_message, 2)
+
+
// Show a message to all mobs in sight of this atom
// Use for objects performing visible actions
// message is output to anyone who can see, e.g. "The [src] does something!"
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
/atom/proc/visible_message(var/message, var/blind_message)
- for(var/mob/M in viewers(src))
+ var/list/messageturfs = list()//List of turfs we broadcast to.
+ var/list/messagemobs = list()//List of living mobs nearby who can hear it, and distant ghosts who've chosen to hear it
+ for (var/turf in view(world.view, get_turf(src)))
+ messageturfs += turf
+
+ for(var/mob/M in player_list)
+ if (!M.client)
+ continue
+ if(get_turf(M) in messageturfs)
+ messagemobs += M
+
+ for(var/mob/M in messagemobs)
M.show_message( message, 1, blind_message, 2)
+
// Returns an amount of power drawn from the object (-1 if it's not viable).
// If drain_check is set it will not actually drain power, just return a value.
// If surge is set, it will destroy/damage the recipient and not return any power.
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 3d353384927..4a4f66d7130 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -19,7 +19,7 @@ em {font-style: normal;font-weight: bold;}
.ooc img.text_tag {width: 32px; height: 10px;}
.ooc .everyone {color: #002eb8;}
-.ooc .looc {color: #3A9696;}
+.ooc .looc {color: #6699CC;}
.ooc .elevated {color: #2e78d9;}
.ooc .moderator {color: #184880;}
.ooc .developer {color: #1b521f;}
diff --git a/html/changelogs/Nanako-ContainedMessages.yml b/html/changelogs/Nanako-ContainedMessages.yml
new file mode 100644
index 00000000000..63469dc5374
--- /dev/null
+++ b/html/changelogs/Nanako-ContainedMessages.yml
@@ -0,0 +1,39 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Nanako
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - bugfix: "LOOC, visible messages and visible emotes now work properly for contained mobs, including PAIs in card form, and any kind of held anima/nymph/drone"
+ - bugfix: "MAJOR USABILITY FIX: Distant ghosts no longer see emotes from NPC mobs, like squeaking mice and clacking crabs. Ghost sight will now only show emotes from distant players, turning it on is now useful."
+ - tweak: "LOOC Colour changed to an older one."
+
\ No newline at end of file