diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm
index 2e35365b3b6..5675abd130d 100644
--- a/code/__DEFINES/say.dm
+++ b/code/__DEFINES/say.dm
@@ -29,3 +29,6 @@
#define ITALICS 1
#define REDUCE_RANGE 2
#define NOPASS 4
+
+// A link given to alice to follow bob
+#define FOLLOW_LINK(alice, bob) "(F)"
diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm
index 9f4b0d76b40..6cf376f602a 100644
--- a/code/game/gamemodes/blob/blobs/blob_mobs.dm
+++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm
@@ -67,7 +67,8 @@
if(isovermind(M) || istype(M, /mob/living/simple_animal/hostile/blob))
M << rendered
if(isobserver(M))
- M << "(F) [rendered]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [rendered]"
////////////////
// BLOB SPORE //
diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm
index d2460d93376..3b712515d88 100644
--- a/code/game/gamemodes/blob/overmind.dm
+++ b/code/game/gamemodes/blob/overmind.dm
@@ -135,7 +135,8 @@
if(isovermind(M) || istype(M, /mob/living/simple_animal/hostile/blob))
M << rendered
if(isobserver(M))
- M << "(F) [rendered]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [rendered]"
/mob/camera/blob/emote(act,m_type=1,message = null)
return
diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm
index 0af0525f908..606583e54ea 100644
--- a/code/game/gamemodes/cult/cult_comms.dm
+++ b/code/game/gamemodes/cult/cult_comms.dm
@@ -37,7 +37,8 @@
if(iscultist(M))
M << my_message
else if(M in dead_mob_list)
- M << "(F) [my_message]"
+ var/link = FOLLOW_LINK(M, user)
+ M << "[link] [my_message]"
log_say("[user.real_name]/[user.key] : [message]")
@@ -72,4 +73,4 @@
var/datum/browser/popup = new(usr, "mind", "", 800, 600)
popup.set_content(text)
popup.open()
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm
index 954b04d2b18..57ba98a1737 100644
--- a/code/game/gamemodes/gang/recaller.dm
+++ b/code/game/gamemodes/gang/recaller.dm
@@ -334,7 +334,8 @@
if(ganger.current && (ganger.current.z <= 2) && (ganger.current.stat == CONSCIOUS))
ganger.current << ping
for(var/mob/M in dead_mob_list)
- M << "(F) [ping]"
+ var/link = FOLLOW_LINK(M, user)
+ M << "[link] [ping]"
log_game("[key_name(user)] Messaged [gang.name] Gang: [message].")
diff --git a/code/game/gamemodes/handofgod/actions.dm b/code/game/gamemodes/handofgod/actions.dm
index 9f6b01f8dff..766a2522fde 100644
--- a/code/game/gamemodes/handofgod/actions.dm
+++ b/code/game/gamemodes/handofgod/actions.dm
@@ -20,8 +20,9 @@
owner << rendered
for(var/mob/M in mob_list)
if(isobserver(M))
- M << "(F) [rendered]"
+ var/link = FOLLOW_LINK(M, owner)
+ M << "[link] [rendered]"
/datum/action/innate/godspeak/Destroy()
god = null
- return ..()
\ No newline at end of file
+ return ..()
diff --git a/code/game/gamemodes/handofgod/god.dm b/code/game/gamemodes/handofgod/god.dm
index 39deb470840..dc745f5c8dc 100644
--- a/code/game/gamemodes/handofgod/god.dm
+++ b/code/game/gamemodes/handofgod/god.dm
@@ -203,7 +203,8 @@
if(is_handofgod_god(M) || is_handofgod_myfollowers(M))
M << rendered
if(isobserver(M))
- M << "(F) [rendered]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [rendered]"
/mob/camera/god/emote(act,m_type = 1 ,msg = null)
@@ -284,4 +285,4 @@
var/datum/browser/popup = new(src, "traps", "Place Trap",350,500)
popup.set_content(dat)
- popup.open()
\ No newline at end of file
+ popup.open()
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 85318857b5c..de4443926b8 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -544,10 +544,12 @@
/mob/living/simple_animal/hostile/swarmer/proc/ContactSwarmers()
var/message = input(src, "Announce to other swarmers", "Swarmer contact")
+ // TODO get swarmers their own colour rather than just boldtext
var/rendered = "Swarm communication - [src] states: [message]"
if(message)
for(var/mob/M in mob_list)
if(isswarmer(M))
M << rendered
- if(M in dead_mob_list)
- M << "(F) [rendered]"
+ if(isobserver(M))
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [rendered]"
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index 029e577f0fb..67384418a95 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -149,7 +149,8 @@
if(istype(M, /mob/living/simple_animal/revenant))
M << rendered
if(isobserver(M))
- M << "(F) [rendered]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [rendered]"
return
diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
index d03f94b1164..ffdac93bf44 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
@@ -121,10 +121,12 @@
for(var/ded in dead_mob_list)
if(!isobserver(ded))
continue
- ded << "(F) \
+ var/follow_rev = FOLLOW_LINK(ded, user)
+ var/follow_whispee = FOLLOW_LINK(ded, M)
+ ded << "[follow_rev] \
[user] \
Revenant Transmit --> \
- (F) \
+ [follow_whispee] \
[M] \
[msg]"
diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm
index 4a4860b3dcd..41f37f98540 100644
--- a/code/game/gamemodes/shadowling/shadowling_abilities.dm
+++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm
@@ -288,8 +288,9 @@
for(var/mob/M in mob_list)
if(is_shadow_or_thrall(M))
M << my_message
- if(M in dead_mob_list)
- M << "(F) [my_message]"
+ if(isobserver(M))
+ var/link = FOLLOW_LINK(M, user)
+ M << "[link] [my_message]"
@@ -750,7 +751,8 @@
if(is_shadow_or_thrall(M))
M << text
if(isobserver(M))
- M << "(F) [text]"
+ var/link = FOLLOW_LINK(M, user)
+ M << "[link] [text]"
log_say("[user.real_name]/[user.key] : [text]")
@@ -893,5 +895,6 @@
if(is_shadow_or_thrall(M))
M << text
if(isobserver(M))
- M << "(F) [text]"
+ var/link = FOLLOW_LINK(M, user)
+ M << "[link] [text]"
log_say("[user.real_name]/[user.key] : [text]")
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index dec0a8d6acc..59c5f953ddb 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -619,7 +619,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/proc/show_to_ghosts(mob/living/user, datum/data_pda_msg/msg,multiple = 0)
for(var/mob/M in player_list)
if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA))
- M << "(F) [msg.sender] PDA Message --> [multiple ? "Everyone" : msg.recipient]: [msg.message][msg.get_photo_ref()]"
+ var/link = FOLLOW_LINK(M, user)
+ M << "[link] [msg.sender] PDA Message --> [multiple ? "Everyone" : msg.recipient]: [msg.message][msg.get_photo_ref()]"
/obj/item/device/pda/proc/can_send(obj/item/device/pda/P)
if(!P || qdeleted(P) || P.toff)
diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm
index ca7202d88d5..533e4bc3a5f 100644
--- a/code/modules/mob/dead/observer/say.dm
+++ b/code/modules/mob/dead/observer/say.dm
@@ -29,5 +29,6 @@
speaker = S.eyeobj
else
speaker = V.source
- src << "(F) [message]"
+ var/link = FOLLOW_LINK(src, speaker)
+ src << "[link] [message]"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index a7ebbeae68a..5bf70cfc2b9 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -91,10 +91,12 @@ Doesn't work on other aliens/AI.*/
for(var/ded in dead_mob_list)
if(!isobserver(ded))
continue
- ded << "(F) \
+ var/follow_link_user = FOLLOW_LINK(ded, user)
+ var/follow_link_whispee = FOLLOW_LINK(ded, M)
+ ded << "[follow_link_user] \
[user] \
Alien Whisper --> \
- (F) \
+ [follow_link_whispee] \
[M] \
[msg]"
else
diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm
index e72008ba098..39539a1a4a9 100644
--- a/code/modules/mob/living/carbon/alien/say.dm
+++ b/code/modules/mob/living/carbon/alien/say.dm
@@ -9,7 +9,8 @@
if(!S.stat && S.hivecheck())
S << rendered
if(S in dead_mob_list)
- S << "(F) [rendered]"
+ var/link = FOLLOW_LINK(S, src)
+ S << "[link] [rendered]"
/mob/living/carbon/alien/humanoid/royal/queen/alien_talk(message, shown_name = name)
shown_name = "[shown_name]"
@@ -18,4 +19,4 @@
/mob/living/carbon/hivecheck()
var/obj/item/organ/alien/hivenode/N = getorgan(/obj/item/organ/alien/hivenode)
if(N && !N.recent_queen_death) //Mob has alien hive node and is not under the dead queen special effect.
- return N
\ No newline at end of file
+ return N
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index b5cfbf412a0..3aa10d00342 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -208,7 +208,8 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
var/msg = "[src.mind]: [message]"
for(var/mob/M in mob_list)
if(M in dead_mob_list)
- M << "(F) [msg]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [msg]"
else
switch(M.lingcheck())
if(3)
@@ -224,7 +225,8 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
log_say("[mind.changeling.changelingID]/[src.key] : [message]")
for(var/mob/M in mob_list)
if(M in dead_mob_list)
- M << "(F) [msg]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [msg]"
else
switch(M.lingcheck())
if(3)
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index acb2e55dc96..180baa73552 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -18,7 +18,14 @@
else
M << rendered
if(isobserver(M))
- M << "(F) [rendered]"
+ var/following = src
+ // If the AI talks on binary chat, we still want to follow
+ // it's camera eye, like if it talked on the radio
+ if(istype(src, /mob/living/silicon/ai))
+ var/mob/living/silicon/ai/ai = M
+ following = ai.eyeobj
+ var/link = FOLLOW_LINK(M, following)
+ M << "[link] [rendered]"
/mob/living/silicon/binarycheck()
return 1
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/say.dm b/code/modules/mob/living/simple_animal/friendly/drone/say.dm
index d4e5ba43abe..8a11b4e86cf 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/say.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/say.dm
@@ -26,9 +26,10 @@
if(istype(M) && M.stat != DEAD && faction_check(M)) //if it's a living drone with matching factions, it gets a message
M << msg
if(dead_can_hear && (M in dead_mob_list))
- M << "(F) [msg]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [msg]"
/mob/living/simple_animal/drone/proc/drone_chat(msg)
var/rendered = "DRONE CHAT: [name]: [msg]"
- alert_drones(rendered, 1)
\ No newline at end of file
+ alert_drones(rendered, 1)
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index f7c69dbf8f5..5a2df11e5f9 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -275,7 +275,8 @@ var/global/list/parasites = list() //all currently existing/living guardians
for(var/para in guardians)
para << my_message
for(var/M in dead_mob_list)
- M << "(F) [my_message]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [my_message]"
log_say("[src.real_name]/[src.key] : [input]")
@@ -296,7 +297,8 @@ var/global/list/parasites = list() //all currently existing/living guardians
var/mob/living/simple_animal/hostile/guardian/G = para
G << "[src]: [preliminary_message]" //but for guardians, use their color for the source instead
for(var/M in dead_mob_list)
- M << "(F) [my_message]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [my_message]"
log_say("[src.real_name]/[src.key] : [text]")
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index e65ab6113d5..3c7f50028fe 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -62,7 +62,8 @@
if(K && M.client && K in M.client.prefs.ignoring)
continue
if(istype(M, /mob/dead/observer))
- M << "(F) [rendered]"
+ var/link = FOLLOW_LINK(M, src)
+ M << "[link] [rendered]"
else
M << "[rendered]"
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 9e6f3e9dbae..b051541a2c7 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -1,4 +1,3 @@
-
/obj/item/organ
name = "organ"
icon = 'icons/obj/surgery.dmi'
@@ -326,7 +325,8 @@
continue
H << rendered
for(var/mob/M in dead_mob_list)
- M << "(F) [rendered]"
+ var/link = FOLLOW_LINK(M, user)
+ M << "[link] [rendered]"
return ""
/obj/item/organ/tongue/zombie