diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 5988f2fc249..8f577018a2e 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -140,6 +140,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_INCAPACITATED "incapacitated"
/// In some kind of critical condition. Is able to succumb.
#define TRAIT_CRITICAL_CONDITION "critical-condition"
+/// Whitelist for mobs that can read or write
+#define TRAIT_LITERATE "literate"
+/// Blacklist for mobs that can't read or write
#define TRAIT_ILLITERATE "illiterate"
#define TRAIT_BLIND "blind"
#define TRAIT_MUTE "mute"
diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm
index 392d25faec3..946b90a8d98 100644
--- a/code/_globalvars/traits.dm
+++ b/code/_globalvars/traits.dm
@@ -13,6 +13,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_RESTRAINED" = TRAIT_RESTRAINED,
"TRAIT_INCAPACITATED" = TRAIT_INCAPACITATED,
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
+ "TRAIT_LITERATE" = TRAIT_LITERATE,
"TRAIT_ILLITERATE" = TRAIT_ILLITERATE,
"TRAIT_BLIND" = TRAIT_BLIND,
"TRAIT_MUTE" = TRAIT_MUTE,
diff --git a/code/datums/mutations/passive.dm b/code/datums/mutations/passive.dm
index 6024d212be0..1c6d130b9e5 100644
--- a/code/datums/mutations/passive.dm
+++ b/code/datums/mutations/passive.dm
@@ -24,8 +24,10 @@
if(..())
return
ADD_TRAIT(owner, TRAIT_ADVANCEDTOOLUSER, GENETIC_MUTATION)
+ ADD_TRAIT(owner, TRAIT_LITERATE, GENETIC_MUTATION)
/datum/mutation/human/clever/on_losing(mob/living/carbon/human/owner)
if(..())
return
REMOVE_TRAIT(owner, TRAIT_ADVANCEDTOOLUSER, GENETIC_MUTATION)
+ REMOVE_TRAIT(owner, TRAIT_LITERATE, GENETIC_MUTATION)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 2e35bc1ec92..71644b5133b 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -814,9 +814,6 @@
return FALSE
return ..()
-/mob/living/carbon/human/is_literate()
- return !HAS_TRAIT(src, TRAIT_ILLITERATE)
-
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
if(blood && (NOBLOOD in dna.species.species_traits) && !HAS_TRAIT(src, TRAIT_TOXINLOVER))
if(message)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index d851c8d124d..b508820d30d 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -174,7 +174,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
///Species-only traits. Can be found in [code/__DEFINES/DNA.dm]
var/list/species_traits = list()
///Generic traits tied to having the species.
- var/list/inherent_traits = list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP)
+ var/list/inherent_traits = list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP, TRAIT_LITERATE)
/// List of biotypes the mob belongs to. Used by diseases.
var/inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID
///List of factions the mob gain upon gaining this species.
diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm
index c2519002f91..ef4838813aa 100644
--- a/code/modules/mob/living/carbon/human/species_types/abductors.dm
+++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm
@@ -11,6 +11,7 @@
TRAIT_CHUNKYFINGERS,
TRAIT_NOHUNGER,
TRAIT_NOBREATH,
+ TRAIT_LITERATE,
)
mutanttongue = /obj/item/organ/tongue/abductor
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm
index c7ea0bdc4c1..838fe0600f7 100644
--- a/code/modules/mob/living/carbon/human/species_types/android.dm
+++ b/code/modules/mob/living/carbon/human/species_types/android.dm
@@ -21,6 +21,7 @@
TRAIT_LIMBATTACHMENT,
TRAIT_NOCLONELOSS,
TRAIT_CAN_USE_FLIGHT_POTION,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
meat = null
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
index 03b0616a2f3..31da6805a7e 100644
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
@@ -7,6 +7,7 @@
TRAIT_CAN_STRIP,
TRAIT_NOHUNGER,
TRAIT_NOBREATH,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutant_bodyparts = list("wings" = "None")
diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
index 7b130210bbd..86a55a5dbc6 100644
--- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
@@ -8,6 +8,7 @@
TRAIT_ADVANCEDTOOLUSER,
TRAIT_CAN_STRIP,
TRAIT_CAN_USE_FLIGHT_POTION,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
meat = /obj/item/food/meat/slab/human/mutant/fly
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 211b8c00084..3c0cba24b31 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -17,6 +17,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
mutant_organs = list(/obj/item/organ/adamantine_resonator)
@@ -122,6 +123,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
info_text = "As a Plasma Golem, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!"
heatmod = 0 //fine until they blow up
@@ -332,6 +334,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_ORGANIC | MOB_HUMANOID | MOB_PLANT
armor = 30
@@ -603,6 +606,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
punchdamagelow = 0
punchdamagehigh = 1
@@ -711,6 +715,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
prefix = "Runic"
@@ -786,6 +791,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_CHUNKYFINGERS,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
armor = 15 //feels no pain, but not too resistant
@@ -961,6 +967,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_VENTCRAWLER_NUDE,
+ TRAIT_LITERATE,
)
prefix = "Plastic"
special_names = list("Sheet", "Bag", "Bottle")
@@ -1058,6 +1065,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_NOFLASH,
+ TRAIT_LITERATE,
)
attack_verb = "whips"
attack_sound = 'sound/weapons/whip.ogg'
@@ -1123,6 +1131,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_STRONG_GRABBER,
+ TRAIT_LITERATE,
)
prefix = "Leather"
fixed_mut_color = "#624a2e"
@@ -1150,6 +1159,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_NOFLASH,
+ TRAIT_LITERATE,
)
info_text = "As a Durathread Golem, your strikes will cause those your targets to start choking, but your woven body won't withstand fire as well."
bodypart_overrides = list(
@@ -1195,6 +1205,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_FAKEDEATH,
+ TRAIT_LITERATE,
)
species_language_holder = /datum/language_holder/golem/bone
info_text = "As a Bone Golem, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice."
@@ -1304,6 +1315,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
bodypart_overrides = list(
BODY_ZONE_L_ARM = /obj/item/bodypart/l_arm/golem/snow,
@@ -1370,6 +1382,7 @@
TRAIT_GENELESS,
TRAIT_NODISMEMBER,
TRAIT_CHUNKYFINGERS,
+ TRAIT_LITERATE,
)
examine_limb_id = SPECIES_GOLEM
diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm
index 490ca6e01f6..f08ca038bd1 100644
--- a/code/modules/mob/living/carbon/human/species_types/humans.dm
+++ b/code/modules/mob/living/carbon/human/species_types/humans.dm
@@ -6,6 +6,7 @@
TRAIT_ADVANCEDTOOLUSER,
TRAIT_CAN_STRIP,
TRAIT_CAN_USE_FLIGHT_POTION,
+ TRAIT_LITERATE,
)
mutant_bodyparts = list("wings" = "None")
use_skintones = 1
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index fe57be2bfa5..a6268ff8603 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -9,6 +9,7 @@
TRAIT_ADVANCEDTOOLUSER,
TRAIT_CAN_STRIP,
TRAIT_TOXINLOVER,
+ TRAIT_LITERATE,
)
mutantlungs = /obj/item/organ/lungs/slime
meat = /obj/item/food/meat/slab/human/mutant/slime
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index d86df6ed5cd..8ab9caec732 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -9,6 +9,7 @@
TRAIT_ADVANCEDTOOLUSER,
TRAIT_CAN_STRIP,
TRAIT_CAN_USE_FLIGHT_POTION,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE
mutant_bodyparts = list("tail_lizard" = "Smooth", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs")
@@ -195,7 +196,7 @@ Lizard subspecies: ASHWALKERS
TRAIT_CAN_STRIP,
TRAIT_CHUNKYFINGERS,
TRAIT_VIRUSIMMUNE,
- TRAIT_ILLITERATE,
+ //TRAIT_LITERATE, ashwalkers are uneducated hillbillies from lavaland
)
species_language_holder = /datum/language_holder/lizard/ash
digitigrade_customization = DIGITIGRADE_FORCED
@@ -217,6 +218,7 @@ Lizard subspecies: SILVER SCALED
TRAIT_PIERCEIMMUNE,
TRAIT_VIRUSIMMUNE,
TRAIT_WINE_TASTER,
+ TRAIT_LITERATE,
)
species_language_holder = /datum/language_holder/lizard //SKYRAT EDIT CHANGE
mutanttongue = /obj/item/organ/tongue/lizard //SKYRAT EDIT CHANGE
diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm
index f765a14c1d1..55dae5d6ac4 100644
--- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm
+++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm
@@ -28,6 +28,7 @@
TRAIT_PRIMITIVE,
TRAIT_WEAK_SOUL,
TRAIT_GUN_NATURAL,
+ //TRAIT_LITERATE, monkeys shouldn't be able to read or write
)
no_equip = list(
ITEM_SLOT_OCLOTHING,
diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm
index 16d31e7b739..133894f492b 100644
--- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm
@@ -8,6 +8,7 @@
TRAIT_ADVANCEDTOOLUSER,
TRAIT_CAN_STRIP,
TRAIT_CAN_USE_FLIGHT_POTION,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
mutant_bodyparts = list("moth_markings" = "None")
diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
index a6daaf13c0f..68e7292834f 100644
--- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
@@ -16,6 +16,7 @@
TRAIT_CAN_STRIP,
TRAIT_NOBREATH,
TRAIT_NOFLASH,
+ TRAIT_LITERATE,
)
inherent_factions = list("mushroom")
speedmod = 1.5 //faster than golems but not by much
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index a54056ba7c1..595541e0c93 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -15,6 +15,7 @@
TRAIT_GENELESS,
TRAIT_NOHUNGER,
TRAIT_HARDLY_WOUNDED,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index 1ea399294fd..d9b79ffd3dd 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -8,6 +8,7 @@
TRAIT_ADVANCEDTOOLUSER,
TRAIT_CAN_STRIP,
TRAIT_PLANT_SAFE,
+ TRAIT_LITERATE,
)
external_organs = list(
/obj/item/organ/external/pod_hair = "None",
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 8c0ec6ae83d..95e0e14518d 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -12,6 +12,7 @@
TRAIT_RADIMMUNE,
TRAIT_VIRUSIMMUNE,
TRAIT_NOBREATH,
+ TRAIT_LITERATE,
)
inherent_factions = list("faithless")
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC
diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
index 67b0712254e..daa5188389f 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -26,6 +26,7 @@
TRAIT_XENO_IMMUNE,
TRAIT_NOCLONELOSS,
TRAIT_CAN_USE_FLIGHT_POTION,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutanttongue = /obj/item/organ/tongue/bone
diff --git a/code/modules/mob/living/carbon/human/species_types/snail.dm b/code/modules/mob/living/carbon/human/species_types/snail.dm
index 5e4e624e02f..a686ac7a954 100644
--- a/code/modules/mob/living/carbon/human/species_types/snail.dm
+++ b/code/modules/mob/living/carbon/human/species_types/snail.dm
@@ -6,6 +6,7 @@
TRAIT_ADVANCEDTOOLUSER,
TRAIT_CAN_STRIP,
TRAIT_NOSLIPALL,
+ TRAIT_LITERATE,
TRAIT_WATER_BREATHING, //SKYRAT EDIT - Roundstart Snails
)
attack_verb = "slap"
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index ec4a11ad709..5c1f5fec81a 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -22,6 +22,7 @@
TRAIT_CAN_STRIP,
TRAIT_NOHUNGER,
TRAIT_NOBREATH,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutant_bodyparts = list("wings" = "None")
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 797d64bc62b..aeef955ad8b 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -25,6 +25,7 @@
TRAIT_NODEATH,
TRAIT_FAKEDEATH,
TRAIT_NOCLONELOSS,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutanttongue = /obj/item/organ/tongue/zombie
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 8d1a2d78de6..c754b3836c4 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -65,8 +65,7 @@
ADD_TRAIT(src, TRAIT_MARTIAL_ARTS_IMMUNE, ROUNDSTART_TRAIT)
ADD_TRAIT(src, TRAIT_NOFIRE_SPREAD, ROUNDSTART_TRAIT)
ADD_TRAIT(src, TRAIT_ASHSTORM_IMMUNE, ROUNDSTART_TRAIT)
-
-
+ ADD_TRAIT(src, TRAIT_LITERATE, ROUNDSTART_TRAIT)
/mob/living/silicon/Destroy()
QDEL_NULL(radio)
@@ -404,9 +403,6 @@
if (aicamera)
return aicamera.selectpicture(user)
-/mob/living/silicon/is_literate()
- return TRUE
-
/mob/living/silicon/get_inactive_held_item()
return FALSE
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index 0fc25b78950..0f280ad651c 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -186,6 +186,7 @@
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
ADD_TRAIT(src, TRAIT_NEGATES_GRAVITY, INNATE_TRAIT)
+ ADD_TRAIT(src, TRAIT_LITERATE, INNATE_TRAIT)
listener = new(list(ALARM_ATMOS, ALARM_FIRE, ALARM_POWER), list(z))
RegisterSignal(listener, COMSIG_ALARM_TRIGGERED, .proc/alarm_triggered)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 62843db0917..4e7857a2d29 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1179,7 +1179,7 @@
/// This mob is abile to read books
/mob/proc/is_literate()
- return FALSE
+ return HAS_TRAIT(src, TRAIT_LITERATE) && !HAS_TRAIT(src, TRAIT_ILLITERATE)
/// Can this mob write
/mob/proc/can_write(obj/writing_instrument)
diff --git a/code/modules/modular_computers/file_system/programs/ntmessenger.dm b/code/modules/modular_computers/file_system/programs/ntmessenger.dm
index 3d6eb7b6310..dbf8c6a428f 100644
--- a/code/modules/modular_computers/file_system/programs/ntmessenger.dm
+++ b/code/modules/modular_computers/file_system/programs/ntmessenger.dm
@@ -351,7 +351,7 @@
if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis
inbound_message = emoji_parse(inbound_message)
- if(ringer_status)
+ if(ringer_status && L.is_literate())
to_chat(L, "[icon2html(src)] PDA message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [inbound_message] [reply]")