diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 03b156de665..6ca33a53847 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 6e7ffe5a38a..098ca2af105 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 1dcc00a9eee..211238f54f3 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -772,9 +772,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 a5996aec183..367276b21de 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -173,7 +173,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 056f13623c8..959e79cda73 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/internal/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 7c1f24f6968..5d46dc4caf7 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 1cdca7279be..e85958258db 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 f3d58a512ff..9cb6eef50fe 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 930923cd5e2..210f856bd10 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/internal/adamantine_resonator)
@@ -124,6 +125,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
@@ -334,6 +336,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_ORGANIC | MOB_HUMANOID | MOB_PLANT
armor = 30
@@ -605,6 +608,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
punchdamagelow = 0
punchdamagehigh = 1
@@ -713,6 +717,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
prefix = "Runic"
@@ -788,6 +793,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_CHUNKYFINGERS,
+ TRAIT_LITERATE,
)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
armor = 15 //feels no pain, but not too resistant
@@ -963,6 +969,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_VENTCRAWLER_NUDE,
+ TRAIT_LITERATE,
)
prefix = "Plastic"
special_names = list("Sheet", "Bag", "Bottle")
@@ -1060,6 +1067,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_NOFLASH,
+ TRAIT_LITERATE,
)
attack_verb = "whips"
attack_sound = 'sound/weapons/whip.ogg'
@@ -1125,6 +1133,7 @@
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
TRAIT_STRONG_GRABBER,
+ TRAIT_LITERATE,
)
prefix = "Leather"
fixed_mut_color = "#624a2e"
@@ -1152,6 +1161,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(
@@ -1197,6 +1207,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."
@@ -1306,6 +1317,7 @@
TRAIT_GENELESS,
TRAIT_PIERCEIMMUNE,
TRAIT_NODISMEMBER,
+ TRAIT_LITERATE,
)
bodypart_overrides = list(
BODY_ZONE_L_ARM = /obj/item/bodypart/l_arm/golem/snow,
@@ -1372,6 +1384,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 e7a60373105..ab6b4eea868 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/internal/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 d175613706e..b856955f96f 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("body_markings" = "None", "legs" = "Normal Legs")
@@ -136,7 +137,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
@@ -158,6 +159,7 @@ Lizard subspecies: SILVER SCALED
TRAIT_PIERCEIMMUNE,
TRAIT_VIRUSIMMUNE,
TRAIT_WINE_TASTER,
+ TRAIT_LITERATE,
)
species_language_holder = /datum/language_holder/lizard/silver
mutanttongue = /obj/item/organ/internal/tongue/lizard/silver
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 0bb54535c16..2f95629d20f 100644
--- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm
+++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm
@@ -29,6 +29,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 1800cdd52cf..8d144cae493 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 876634c5db1..551f5320b00 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 39dfd44a0a2..a9dadf77e15 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 eec8917fb98..c97af3b8abe 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 bdcc3f150f9..b2e2e95749f 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 e1da28b300e..35f96d4e623 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/internal/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 6c0a1355724..6062e461788 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,
)
attack_verb = "slap"
attack_effect = ATTACK_EFFECT_DISARM
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 9201a2f870d..b8985058477 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 c051c8e3bd8..3793c4e628a 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/internal/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 58249e36f39..3c0006dec05 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 bb88f2f91bf..8c88d9bc7ee 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1152,7 +1152,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]")