diff --git a/code/__DEFINES/memory_defines.dm b/code/__DEFINES/memory_defines.dm
index f35761fe82c..7229b70c4da 100644
--- a/code/__DEFINES/memory_defines.dm
+++ b/code/__DEFINES/memory_defines.dm
@@ -44,6 +44,14 @@
#define MEMORY_FLAG_NOPERSISTENCE (1<<3)
///this memory has already been engraved, and cannot be selected for engraving again.
#define MEMORY_FLAG_ALREADY_USED (1<<4)
+///this memory requires the target not to be blind.
+#define MEMORY_CHECK_BLINDNESS (1<<5)
+///this memory requires the target not to be deaf.
+#define MEMORY_CHECK_DEAFNESS (1<<6)
+///this memory requires the target not to be both deaf and blind.
+#define MEMORY_CHECK_BLIND_AND_DEAF (MEMORY_CHECK_BLINDNESS|MEMORY_CHECK_DEAFNESS)
+///this memory can be memorized by unconscious people.
+#define MEMORY_SKIP_UNCONSCIOUS (1<<8)
//These defines are for what notable event happened. they correspond to the json lists related to the memory
///a memory of completing a surgery.
diff --git a/code/__HELPERS/memory_helpers.dm b/code/__HELPERS/memory_helpers.dm
index 415ddc02f7f..5e3a3140e8f 100644
--- a/code/__HELPERS/memory_helpers.dm
+++ b/code/__HELPERS/memory_helpers.dm
@@ -1,13 +1,19 @@
///Adds a memory to people that can see this happening, only use this for impactful or rare events to reduce overhead.
-/proc/add_memory_in_range(atom/source, range, memory_type, extra_info, story_value, memory_flags)
- for(var/mob/living/carbon/memorizer in hearers(range, source))
+/proc/add_memory_in_range(atom/source, range, memory_type, extra_info, story_value, memory_flags, protagonist_memory_flags)
+ var/list/memorizers = hearers(range, source)
+ if(!isnull(protagonist_memory_flags))
+ var/mob/living/carbon/protagonist = extra_info[DETAIL_PROTAGONIST]
+ if(istype(protagonist))
+ memorizers -= protagonist
+ protagonist.mind?.add_memory(memory_type, extra_info, story_value, protagonist_memory_flags)
+ for(var/mob/living/carbon/memorizer in memorizers)
memorizer.mind?.add_memory(memory_type, extra_info, story_value, memory_flags)
/**
* add_memory
*
- * Adds a memory to a mob's mind, called wherever the memory takes place (memory for catching on fire in mob's fire code, for example)
+ * Adds a memory to a mob's mind if conditions are met, called wherever the memory takes place (memory for catching on fire in mob's fire code, for example)
* Argument:
* * memory_type: defined string in memory_defines.dm, shows the memories.json file which story parts to use (and generally what type it is)
* * extra_info: the contents of the story. You're gonna want at least the protagonist for who is the main character in the story
@@ -16,6 +22,17 @@
* Returns the datum memory created, null otherwise.
*/
/datum/mind/proc/add_memory(memory_type, extra_info, story_value, memory_flags)
+ if(current)
+ if(!(memory_flags & MEMORY_SKIP_UNCONSCIOUS) && current.stat >= UNCONSCIOUS)
+ return
+ var/is_blind = FALSE
+ if(memory_flags & MEMORY_CHECK_BLINDNESS && current.is_blind())
+ if(!(memory_flags & MEMORY_CHECK_DEAFNESS)) // Only check for blindness
+ return
+ is_blind = TRUE // Otherwise check if the mob is both blind and deaf
+ if(memory_flags & MEMORY_CHECK_DEAFNESS && HAS_TRAIT(current, TRAIT_DEAF) && (!(memory_flags & MEMORY_CHECK_BLINDNESS) || is_blind))
+ return
+
var/story_mood = MOODLESS_MEMORY
var/victim_mood = MOODLESS_MEMORY
diff --git a/code/datums/components/creamed.dm b/code/datums/components/creamed.dm
index 7bcd89e6f95..12e2f3e1660 100644
--- a/code/datums/components/creamed.dm
+++ b/code/datums/components/creamed.dm
@@ -19,7 +19,7 @@ GLOBAL_LIST_INIT(creamable, typecacheof(list(
SEND_SIGNAL(parent, COMSIG_MOB_CREAMED)
- add_memory_in_range(parent, 7, MEMORY_CREAMPIED, list(DETAIL_PROTAGONIST = parent), story_value = STORY_VALUE_OKAY)
+ add_memory_in_range(parent, 7, MEMORY_CREAMPIED, list(DETAIL_PROTAGONIST = parent), story_value = STORY_VALUE_OKAY, memory_flags = MEMORY_CHECK_BLINDNESS, protagonist_memory_flags = NONE)
creamface = mutable_appearance('icons/effects/creampie.dmi')
diff --git a/code/datums/components/gunpoint.dm b/code/datums/components/gunpoint.dm
index 36803f903c5..1e64257a6b2 100644
--- a/code/datums/components/gunpoint.dm
+++ b/code/datums/components/gunpoint.dm
@@ -40,7 +40,7 @@
shooter.visible_message(span_danger("[shooter] aims [weapon] point blank at [target]!"), \
span_danger("You aim [weapon] point blank at [target]!"), ignored_mobs = target)
to_chat(target, span_userdanger("[shooter] aims [weapon] point blank at you!"))
- add_memory_in_range(target, 7, MEMORY_GUNPOINT, list(DETAIL_PROTAGONIST = target, DETAIL_DEUTERAGONIST = shooter, DETAIL_WHAT_BY = weapon), story_value = STORY_VALUE_OKAY)
+ add_memory_in_range(target, 7, MEMORY_GUNPOINT, list(DETAIL_PROTAGONIST = target, DETAIL_DEUTERAGONIST = shooter, DETAIL_WHAT_BY = weapon), story_value = STORY_VALUE_OKAY, memory_flags = MEMORY_CHECK_BLINDNESS)
shooter.apply_status_effect(STATUS_EFFECT_HOLDUP, shooter)
target.apply_status_effect(STATUS_EFFECT_HELDUP, shooter)
diff --git a/code/datums/components/spill.dm b/code/datums/components/spill.dm
index 51c0d2e0f24..0349d155331 100644
--- a/code/datums/components/spill.dm
+++ b/code/datums/components/spill.dm
@@ -68,4 +68,4 @@
if(dropsound)
playsound(master, pick(dropsound), 30)
if(drop_memory)
- fool.mind?.add_memory(MEMORY_SPAGHETTI_SPILL, list(DETAIL_PROTAGONIST = fool), story_value = STORY_VALUE_OKAY)
+ fool.mind?.add_memory(MEMORY_SPAGHETTI_SPILL, list(DETAIL_PROTAGONIST = fool), story_value = STORY_VALUE_OKAY, memory_flags = MEMORY_CHECK_BLINDNESS)
diff --git a/code/game/objects/items/hand_items.dm b/code/game/objects/items/hand_items.dm
index 9ef7e62e846..f0102b97448 100644
--- a/code/game/objects/items/hand_items.dm
+++ b/code/game/objects/items/hand_items.dm
@@ -326,15 +326,15 @@
/obj/projectile/kiss/proc/harmless_on_hit(mob/living/living_target)
playsound(get_turf(living_target), hitsound, 100, TRUE)
living_target.visible_message(span_danger("[living_target] is hit by \a [src]."), span_userdanger("You're hit by \a [src]!"), vision_distance=COMBAT_MESSAGE_RANGE)
- living_target.mind?.add_memory(MEMORY_KISS, list(DETAIL_PROTAGONIST = living_target, DETAIL_KISSER = firer), story_value = STORY_VALUE_OKAY)
+ living_target.mind?.add_memory(MEMORY_KISS, list(DETAIL_PROTAGONIST = living_target, DETAIL_KISSER = firer), story_value = STORY_VALUE_OKAY, memory_flags = MEMORY_CHECK_BLINDNESS)
if(isliving(firer))
var/mob/living/kisser = firer
- kisser.mind?.add_memory(MEMORY_KISS, list(DETAIL_PROTAGONIST = living_target, DETAIL_KISSER = firer), story_value = STORY_VALUE_OKAY)
+ kisser.mind?.add_memory(MEMORY_KISS, list(DETAIL_PROTAGONIST = living_target, DETAIL_KISSER = firer), story_value = STORY_VALUE_OKAY, memory_flags = MEMORY_CHECK_BLINDNESS)
try_fluster(living_target)
/obj/projectile/kiss/proc/try_fluster(mob/living/living_target)
// people with the social anxiety quirk can get flustered when hit by a kiss
- if(!HAS_TRAIT(living_target, TRAIT_ANXIOUS) || (living_target.stat > SOFT_CRIT))
+ if(!HAS_TRAIT(living_target, TRAIT_ANXIOUS) || (living_target.stat > SOFT_CRIT) || living_target.is_blind())
return
if(HAS_TRAIT(living_target, TRAIT_FEARLESS) || prob(50)) // 50% chance for it to apply, also immune while on meds
return
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index d9367b78382..2658e640868 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -299,7 +299,7 @@
O.mmi = W //and give the real mmi to the borg.
O.updatename(brainmob.client)
brainmob.mind.transfer_to(O)
- brainmob.mind.add_memory(MEMORY_BORGED, list(DETAIL_PROTAGONIST = user), story_value = STORY_VALUE_OKAY)
+ brainmob.mind.add_memory(MEMORY_BORGED, list(DETAIL_PROTAGONIST = user), story_value = STORY_VALUE_OKAY, memory_flags = MEMORY_SKIP_UNCONSCIOUS)
playsound(O.loc, 'sound/voice/liveagain.ogg', 75, TRUE)
if(O.mind && O.mind.special_role)
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index bbec23bca52..fcd86ae96ac 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -429,7 +429,7 @@
LAZYADD(rev_mind.special_statuses, "Former revolutionary")
else
LAZYADD(rev_mind.special_statuses, "Former head revolutionary")
- add_memory_in_range(rev_mind.current, 7, MEMORY_WON_REVOLUTION, list(DETAIL_PROTAGONIST = rev_mind.current, DETAIL_STATION_NAME = station_name()), story_value = STORY_VALUE_LEGENDARY, memory_flags = MEMORY_FLAG_NOSTATIONNAME)
+ add_memory_in_range(rev_mind.current, 7, MEMORY_WON_REVOLUTION, list(DETAIL_PROTAGONIST = rev_mind.current, DETAIL_STATION_NAME = station_name()), story_value = STORY_VALUE_LEGENDARY, memory_flags = MEMORY_FLAG_NOSTATIONNAME|MEMORY_CHECK_BLIND_AND_DEAF, protagonist_memory_flags = MEMORY_FLAG_NOSTATIONNAME)
if(!charter_given && rev_mind.current && rev_mind.current.stat == CONSCIOUS)
charter_given = TRUE
podspawn(list(
diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm
index 551d5e22015..2ff2ccf2c14 100644
--- a/code/modules/mob/living/carbon/death.dm
+++ b/code/modules/mob/living/carbon/death.dm
@@ -9,7 +9,7 @@
INVOKE_ASYNC(src, .proc/emote, "deathgasp")
reagents.end_metabolization(src)
- add_memory_in_range(src, 7, MEMORY_DEATH, list(DETAIL_PROTAGONIST = src), memory_flags = MEMORY_FLAG_NOMOOD, story_value = STORY_VALUE_OKAY)
+ add_memory_in_range(src, 7, MEMORY_DEATH, list(DETAIL_PROTAGONIST = src), memory_flags = MEMORY_FLAG_NOMOOD, story_value = STORY_VALUE_OKAY, memory_flags = MEMORY_CHECK_BLIND_AND_DEAF)
. = ..()
@@ -24,7 +24,7 @@
animate(src, time = 40, transform = M, easing = SINE_EASING)
/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts, safe_gib = FALSE)
- add_memory_in_range(src, 7, MEMORY_GIBBED, list(DETAIL_PROTAGONIST = src), STORY_VALUE_AMAZING, MEMORY_FLAG_NOMOOD)
+ add_memory_in_range(src, 7, MEMORY_GIBBED, list(DETAIL_PROTAGONIST = src), STORY_VALUE_AMAZING, MEMORY_FLAG_NOMOOD, memory_flags = MEMORY_CHECK_BLINDNESS)
if(safe_gib) // If you want to keep all the mob's items and not have them deleted
for(var/obj/item/W in src)
dropItemToGround(W)
diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm
index f70fd6f86b5..014e6fc99f9 100644
--- a/code/modules/mob/living/simple_animal/friendly/pet.dm
+++ b/code/modules/mob/living/simple_animal/friendly/pet.dm
@@ -68,7 +68,7 @@
collar_type = "[initial(collar_type)]_dead"
regenerate_icons()
- add_memory_in_range(src, 7, MEMORY_PET_DEAD, list(DETAIL_DEUTERAGONIST = src), story_value = STORY_VALUE_AMAZING) //Protagonist is the person memorizing it
+ add_memory_in_range(src, 7, MEMORY_PET_DEAD, list(DETAIL_DEUTERAGONIST = src), story_value = STORY_VALUE_AMAZING, memory_flags = MEMORY_CHECK_BLIND_AND_DEAF) //Protagonist is the person memorizing it
/mob/living/simple_animal/pet/regenerate_icons()
cut_overlays()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm
index 25d1485fe3a..1f348584eae 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm
@@ -177,7 +177,7 @@
for(var/mob/living/L in grant_achievement)
if(L.stat || !L.client)
continue
- L?.mind.add_memory(MEMORY_MEGAFAUNA_KILL, list(DETAIL_PROTAGONIST = L, DETAIL_DEUTERAGONIST = src), STORY_VALUE_LEGENDARY)
+ L?.mind.add_memory(MEMORY_MEGAFAUNA_KILL, list(DETAIL_PROTAGONIST = L, DETAIL_DEUTERAGONIST = src), STORY_VALUE_LEGENDARY, memory_flags = MEMORY_CHECK_BLIND_AND_DEAF)
L.client.give_award(/datum/award/achievement/boss/boss_killer, L)
L.client.give_award(achievement_type, L)
if(crusher_kill && istype(L.get_active_held_item(), /obj/item/kinetic_crusher))
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 409433ebbd0..85cb0099fb5 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -939,7 +939,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
cause = "contact"
nom.visible_message(vis_msg, mob_msg, span_hear("You hear an unearthly noise as a wave of heat washes over you."))
investigate_log("has been attacked ([cause]) by [key_name(nom)]", INVESTIGATE_SUPERMATTER)
- add_memory_in_range(src, 7, MEMORY_SUPERMATTER_DUSTED, list(DETAIL_PROTAGONIST = nom, DETAIL_WHAT_BY = src), story_value = STORY_VALUE_OKAY)
+ add_memory_in_range(src, 7, MEMORY_SUPERMATTER_DUSTED, list(DETAIL_PROTAGONIST = nom, DETAIL_WHAT_BY = src), story_value = STORY_VALUE_OKAY, memory_flags = MEMORY_CHECK_BLIND_AND_DEAF)
playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE)
Consume(nom)
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index 1a66fe47b0f..0242f8bae1c 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -617,7 +617,7 @@ GLOBAL_LIST_EMPTY(vending_products)
. = TRUE
playsound(L, 'sound/effects/blobattack.ogg', 40, TRUE)
playsound(L, 'sound/effects/splat.ogg', 50, TRUE)
- add_memory_in_range(L, 7, MEMORY_VENDING_CRUSHED, list(DETAIL_PROTAGONIST = L, DETAIL_WHAT_BY = src), story_value = STORY_VALUE_AMAZING)
+ add_memory_in_range(L, 7, MEMORY_VENDING_CRUSHED, list(DETAIL_PROTAGONIST = L, DETAIL_WHAT_BY = src), story_value = STORY_VALUE_AMAZING, memory_flags = MEMORY_CHECK_BLINDNESS, protagonist_memory_flags = MEMORY_SKIP_UNCONSCIOUS)
var/matrix/M = matrix()
M.Turn(pick(90, 270))