diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 3b6d2c8abf0..bb0f4a1bf31 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1558,8 +1558,8 @@
return germs
/mob/living/carbon/human/proc/do_fever_effects(var/fever)
- if(prob(20/3)) // every 30 seconds, roughly
- to_chat(src, SPAN_WARNING(pick("You feel cold and clammy...", "You shiver as if a breeze has passed through.", "Your muscles ache.", "You feel tired and fatigued.")))
+ var/list/fever_messages = list("You feel cold and clammy...", "You shiver as if a breeze has passed through.", "Your muscles ache.", "You feel tired and fatigued.")
+ notify_message(SPAN_WARNING(pick(fever_messages)), 30 SECONDS, key = "fever_effect_message")
if(prob(25)) // once every 8 seconds, roughly
drowsiness += 5
if(prob(20))
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index cecef72857d..d358eaa8f17 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -259,3 +259,6 @@
var/atom/movable/typing_indicator/typing_indicator
/// User is thinking in character. Used to revert to thinking state after stop_typing
var/thinking_IC = FALSE
+
+ /// A assoc lazylist of to_chat notifications, key = string message, value = world time integer
+ var/list/message_notifications
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index cb6229479e8..7c0f1ca5370 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -1310,3 +1310,25 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
///Can the mob hear
/mob/proc/can_hear()
return !isdeaf(src)
+
+
+/// Sends a message to the mob if the current world time is less than the previous' message next_message_time, additionally sends a floating message if show_floating_message is set to true. key is an optional replacement that'll go in the assoc list, used for stuff like picklists
+/mob/proc/notify_message(var/message, var/next_message_time = 1 SECOND, var/show_floating_message = FALSE, var/key)
+ // initializes the message_notifications list so we can use standard list handling from here on out
+ // it's only lazy to save memory
+ LAZYINITLIST(message_notifications)
+
+ // if we have a key, use that, otherwise check the message
+ var/key_check = key || message
+ if((key_check in message_notifications) && world.time < message_notifications[key_check])
+ return
+
+ to_chat(src, message)
+ if(show_floating_message)
+ balloon_alert(src, strip_html_full(message))
+
+ // we only keep 10 entries in the assoc list, this is an arbitrary number meant to keep it from ballooning in size and taking up memory
+ if(length(message_notifications) >= 10)
+ message_notifications.Cut(1, 2)
+
+ message_notifications[key_check] = world.time + next_message_time
diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm
index dfd70db65fc..d5eb6b111bb 100644
--- a/code/modules/organs/internal/brain.dm
+++ b/code/modules/organs/internal/brain.dm
@@ -117,28 +117,28 @@
else if(can_heal)
damage = max(damage-1, 0)
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
- if(prob(1))
- to_chat(owner, SPAN_WARNING("You feel a bit [pick("lightheaded","dizzy","pale")]..."))
+ owner.notify_message(SPAN_WARNING("You feel a bit [pick("lightheaded","dizzy","pale")]..."), rand(20 SECONDS, 40 SECONDS), key = "blood_volume_okay")
damprob = owner.chem_effects[CE_STABLE] ? 30 : 60
if(!past_damage_threshold(2) && prob(damprob))
take_internal_damage(1)
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
+ owner.notify_message(SPAN_WARNING("You feel [pick("weak","disoriented","faint","cold")]."), rand(20 SECONDS, 40 SECONDS), key = "blood_volume_bad")
owner.eye_blurry = max(owner.eye_blurry,6)
damprob = owner.chem_effects[CE_STABLE] ? 40 : 80
if(!past_damage_threshold(4) && prob(damprob))
take_internal_damage(1)
if(!owner.paralysis && prob(10))
owner.Paralyse(rand(1,3))
- to_chat(owner, SPAN_WARNING("You feel [pick("weak","disoriented","faint","cold")]."))
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
+ owner.notify_message(SPAN_WARNING("You feel extremely [pick("cold","woozy","faint","weak","confused","tired","lethargic")]."), rand(20 SECONDS, 40 SECONDS), key = "blood_volume_survive")
owner.eye_blurry = max(owner.eye_blurry,6)
damprob = owner.chem_effects[CE_STABLE] ? 60 : 100
if(!past_damage_threshold(6) && prob(damprob))
take_internal_damage(1)
if(!owner.paralysis && prob(15))
owner.Paralyse(rand(3, 5))
- to_chat(owner, SPAN_WARNING("You feel extremely [pick("cold","woozy","faint","weak","confused","tired","lethargic")]."))
if(-(INFINITY) to BLOOD_VOLUME_SURVIVE) // Also see heart.dm, being below this point puts you into cardiac arrest.
+ owner.notify_message(SPAN_DANGER("You feel feel like death is imminent."), rand(20 SECONDS, 40 SECONDS), key = "blood_volume_dying")
owner.eye_blurry = max(owner.eye_blurry,6)
damprob = owner.chem_effects[CE_STABLE] ? 80 : 100
if(prob(damprob))
diff --git a/code/modules/organs/internal/liver.dm b/code/modules/organs/internal/liver.dm
index 03d64d93d3b..cbdb46645cc 100644
--- a/code/modules/organs/internal/liver.dm
+++ b/code/modules/organs/internal/liver.dm
@@ -19,8 +19,7 @@
return
if (germ_level > INFECTION_LEVEL_ONE)
- if(prob(1))
- to_chat(owner, "Your skin itches.")
+ owner.notify_message(SPAN_WARNING("Your skin itches."), 2 MINUTES)
if (germ_level > INFECTION_LEVEL_TWO)
if(prob(1))
spawn owner.delayed_vomit()
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index 0102ce3d398..cca9cbc440d 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -329,12 +329,9 @@
metabolism_min = 0.005
breathe_mul = 0
-/singleton/reagent/mortaphenyl/initial_effect(var/mob/living/carbon/human/M, var/alien, var/holder)
- to_chat(M, SPAN_GOOD(pick("You lean back and begin to fall... and fall... and fall.", "A feeling of ecstasy builds within you.", "You're startled by just how amazing you suddenly feel.")))
-
/singleton/reagent/mortaphenyl/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
- if(prob(3))
- to_chat(M, SPAN_GOOD(pick("You feel soothed and at ease.", "You feel content and at peace.", "You feel a pleasant emptiness.", "You feel like sharing the wonderful memories and feelings you're experiencing.", "All your anxieties fade away.", "You feel like you're floating off the ground.", "You don't want this feeling to end.")))
+ var/list/joy_messages = list("You feel soothed and at ease.", "You feel content and at peace.", "You feel a pleasant emptiness.", "You feel like sharing the wonderful memories and feelings you're experiencing.", "All your anxieties fade away.", "You feel like you're floating off the ground.", "You don't want this feeling to end.")
+ M.notify_message(SPAN_GOOD(pick(joy_messages)), rand(20 SECONDS, 40 SECONDS), key = "morta_affect_blood")
if(check_min_dose(M))
M.add_chemical_effect(CE_PAINKILLER, 50)
@@ -394,12 +391,9 @@
breathe_met = REM * 4 // .8 units per tick
specific_heat = 1.2
-/singleton/reagent/morphine/initial_effect(var/mob/living/carbon/human/M, var/alien, var/holder)
- to_chat(M, SPAN_GOOD(pick("You lean back and begin to fall... and fall... and fall.", "A feeling of ecstasy builds within you.", "You're startled by just how amazing you suddenly feel.")))
-
/singleton/reagent/morphine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
- if(prob(3))
- to_chat(M, SPAN_GOOD(pick("You feel soothed and at ease.", "You feel content and at peace.", "You feel a pleasant emptiness.", "You feel like sharing the wonderful memories and feelings you're experiencing.", "All your anxieties fade away.", "You feel like you're floating off the ground.", "You don't want this feeling to end.")))
+ var/list/joy_messages = list("You feel soothed and at ease.", "You feel content and at peace.", "You feel a pleasant emptiness.", "You feel like sharing the wonderful memories and feelings you're experiencing.", "All your anxieties fade away.", "You feel like you're floating off the ground.", "You don't want this feeling to end.")
+ M.notify_message(SPAN_GOOD(pick(joy_messages)), rand(20 SECONDS, 40 SECONDS), key = "morphine_affect_blood")
if(check_min_dose(M))
M.add_chemical_effect(CE_PAINKILLER, 120)
diff --git a/html/changelogs/geeves-inform_mob.yml b/html/changelogs/geeves-inform_mob.yml
new file mode 100644
index 00000000000..80d67e3aede
--- /dev/null
+++ b/html/changelogs/geeves-inform_mob.yml
@@ -0,0 +1,6 @@
+author: Geeves
+
+delete-after: True
+
+changes:
+ - refactor: "Tweaked some messages to be based on time since last message, instead of being based on probability. This includes low blood messages, infected liver messages, fever messages, and some drug messages."
\ No newline at end of file