Files
MrMelbert 599f8dcd98 Tweaks some hallucinations to not trigger while unconscious or deaf (#94879)
## About The Pull Request

- Fake body
- All delusions
- Eyes in the Dark
- Fake chat messages
- Fake death
- Fake conspicuous messages
- Fake chasms and anomalies
- Mirage items (both self and others)
- Fake malf APCs
- Your Mom
- Xeno attack

Won't trigger while unconscious

- Most fake station messages
- Sound of battle

Won't trigger while deaf

## Why It's Good For The Game

Many of the effects these are mimicking can only trigger while conscious
or able to hear, so if you ARE unconscious or deaf, it makes it
extremely obvious it's a fake effect.

We should instead give them a hallucination that will affect them, like
appearing to be on fire.

## Changelog

🆑 Melbert
add: Hallucinations that don't make sense to trigger while unconscious
or deaf will no longer trigger while unconscious or deaf
/🆑
2026-01-16 17:11:45 -05:00

131 lines
5.5 KiB
Plaintext

/// Sends a fake chat message to the hallucinator.
/datum/hallucination/chat
random_hallucination_weight = 100
hallucination_tier = HALLUCINATION_TIER_COMMON
/// If TRUE, we force the message to be hallucinated from common radio. Only set in New()
var/force_radio
/// If set, a message we force to be picked, rather than an auto-generated message. Only set in New()
var/specific_message
/datum/hallucination/chat/New(mob/living/hallucinator, force_radio = FALSE, specific_message)
src.force_radio = force_radio
src.specific_message = specific_message
return ..()
/// When passed a mob, returns a list of languages that mob could theoretically speak IF a blank slate.
/datum/hallucination/chat/proc/get_hallucinating_spoken_languages(atom/movable/who)
var/override_typepath
if(iscarbon(who))
var/mob/living/carbon/human_who = who
override_typepath = human_who.dna?.species?.species_language_holder
var/datum/language_holder/what_they_speak = GLOB.prototype_language_holders[override_typepath || who.initial_language_holder]
return what_they_speak?.spoken_languages?.Copy() || list()
/datum/hallucination/chat/start()
if(hallucinator.stat >= UNCONSCIOUS)
return FALSE
var/mob/living/carbon/human/speaker
var/list/datum/language/understood_languages = hallucinator.get_language_holder().understood_languages
var/understood_language
if(!force_radio)
var/list/valid_humans = list()
var/list/valid_corpses = list()
for(var/mob/living/carbon/nearby_human in view(hallucinator))
if(nearby_human == hallucinator)
continue
if(nearby_human.stat == DEAD)
valid_corpses += nearby_human
continue
valid_humans += nearby_human
// pick a nearby human which can speak a language the hallucinator understands
for(var/mob/living/carbon/nearby_human in shuffle(valid_humans))
var/list/shared_languages = get_hallucinating_spoken_languages(nearby_human) & understood_languages
if(!length(shared_languages)) // future idea : have people hallucinating off their minds ignore this check
continue
speaker = nearby_human
understood_language = pick(shared_languages)
break
// corpses disrespect language because they're... dead
if(isnull(speaker) && length(valid_corpses))
speaker = pick(valid_corpses)
// Get person to affect if radio hallucination
var/is_radio = force_radio || isnull(speaker)
if(is_radio)
for(var/datum/mind/crew_mind in shuffle(get_crewmember_minds()))
if(crew_mind == hallucinator.mind || !crew_mind.current)
continue
var/list/shared_languages = get_hallucinating_spoken_languages(crew_mind.current) & understood_languages
if(!length(shared_languages))
continue
speaker = crew_mind.current
understood_language = pick(shared_languages)
break
if(isnull(speaker))
return
// Time to generate a message.
// Spans of our message
var/spans = list(speaker.speech_span)
// Contents of our message
var/chosen = specific_message
// If we didn't have a preset one, let's make one up.
if(!chosen)
if(is_radio)
chosen = pick(list("Help!",
"Help [pick_list_replacements(HALLUCINATION_FILE, "location")][prob(50)?"!":"!!"]",
"[pick_list_replacements(HALLUCINATION_FILE, "people")] is [pick_list_replacements(HALLUCINATION_FILE, "accusations")]!",
"[pick_list_replacements(HALLUCINATION_FILE, "people")] has [pick_list_replacements(HALLUCINATION_FILE, "contraband")]!",
"[pick_list_replacements(HALLUCINATION_FILE, "threat")] in [pick_list_replacements(HALLUCINATION_FILE, "location")][prob(50)?"!":"!!"]",
"[pick("Where's [first_name(hallucinator.name)]?", "Set [first_name(hallucinator.name)] to arrest!")]",
"[pick("C","Ai, c","Someone c","Rec")]all the shuttle!",
"AI [pick("rogue", "is dead")]!!",
"Borgs rogue!",
))
else
chosen = pick(list("[pick_list_replacements(HALLUCINATION_FILE, "suspicion")]",
"[pick_list_replacements(HALLUCINATION_FILE, "conversation")]",
"[pick_list_replacements(HALLUCINATION_FILE, "greetings")][first_name(hallucinator.name)]!",
"[pick_list_replacements(HALLUCINATION_FILE, "getout")]",
"[pick_list_replacements(HALLUCINATION_FILE, "weird")]",
"[pick_list_replacements(HALLUCINATION_FILE, "didyouhearthat")]",
"[pick_list_replacements(HALLUCINATION_FILE, "doubt")]",
"[pick_list_replacements(HALLUCINATION_FILE, "aggressive")]",
"[pick_list_replacements(HALLUCINATION_FILE, "help")]!!",
"[pick_list_replacements(HALLUCINATION_FILE, "escape")]",
"I'm infected, [pick_list_replacements(HALLUCINATION_FILE, "infection_advice")]!",
))
chosen = capitalize(chosen)
chosen = replacetext(chosen, "%TARGETNAME%", first_name(hallucinator.name))
// Log the message
feedback_details += "Type: [is_radio ? "Radio" : "Talk"], Source: [speaker.real_name], Message: [chosen]"
var/plus_runechat = hallucinator.client?.prefs.read_preference(/datum/preference/toggle/enable_runechat)
// Display the message
if(!is_radio && !plus_runechat)
var/image/speech_overlay = image('icons/mob/effects/talk.dmi', speaker, "default0", layer = ABOVE_MOB_LAYER)
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(flick_overlay_global), speech_overlay, list(hallucinator.client), 30)
if(plus_runechat)
hallucinator.create_chat_message(speaker, understood_language, chosen, spans)
// And actually show them the message, for real.
var/message = hallucinator.compose_message(speaker, understood_language, chosen, is_radio ? "[FREQ_COMMON]" : null, is_radio ? RADIO_CHANNEL_COMMON : null, is_radio ? RADIO_COLOR_COMMON : null, spans, visible_name = TRUE)
to_chat(hallucinator, message)
// Then clean up.
qdel(src)
return TRUE