Completely refactors hallucinations, and also adds a few (#69706)

* Refactors hallucinations slightly, organizes them

* Refactors hallucination into a status effect

* Further hallucination proper refactoring

* Refactors battle hallucinations

* Refactors "fake item other" hallucination

* Gets it a bit closer to working state

* Refactors screwydoll and fake alerts

* Refactors fake inhand items

* Refactors a few more.
- Fake death
- Fake messages
- Fake sounds
- Projectiles

* Refactoring delusions, hallucination effects

* Furthering the hallucination status effect
- removes copypaste of hallucination pulses

* Almost finalizes the changeover to status effect

* Last staus effect stuff

* Delusion business

* Airlocks, fire, and more delusion stuff

* Finishes screwyhud. It compiles now!

* Swaps screwyhud over to a grouped status effect

* Removes hal_screwyhud

* Comment

* Bugfixing

* image cleaning

* Get rid of this it came back

* What if I finished this branch?

* Oops

* Messing with the randomness

* Mass hallucination tweaks

* +

* Some more mass tweaks

* Review

* Updates

* Unit tests hallucination icons

* More tweaks

* Move folder

* Another re-name

* Minor tweaks

* Anomaly unity

* Mass hallucination buffs

* t

* Sig

* Merge

* Lints

* Unit test already coming in clutch

* Another failure

* Use named args for cause_hallucination via some define trickery

* Some cleanup

* This is better

* adds some hallucinations

* Oops

* More sounds

* Tweaks

* Some additional documentation

* Flash

* Fixes mass hallucination

* Json changes

* Updates documentation

* Json conflicts

* Makes it work

* Missed that one too

* Helpers

* More signalization (WIP)

* Fixes bump

* Missed a helper use

* Dumb
This commit is contained in:
MrMelbert
2022-09-21 01:30:04 -04:00
committed by GitHub
parent 1ce23e0b57
commit 6baebf47a1
124 changed files with 4040 additions and 2418 deletions
+9 -5
View File
@@ -58,11 +58,15 @@
/datum/brain_trauma/hypnosis/on_life(delta_time, times_fired)
..()
if(DT_PROB(1, delta_time))
switch(rand(1,2))
if(1)
to_chat(owner, span_hypnophrase("<i>...[lowertext(hypnotic_phrase)]...</i>"))
if(2)
new /datum/hallucination/chat(owner, TRUE, FALSE, span_hypnophrase("[hypnotic_phrase]"))
if(prob(50))
to_chat(owner, span_hypnophrase("<i>...[lowertext(hypnotic_phrase)]...</i>"))
else
owner.cause_hallucination( \
/datum/hallucination/chat, \
"hypnosis", \
force_radio = TRUE, \
specific_message = span_hypnophrase("[hypnotic_phrase]"), \
)
/datum/brain_trauma/hypnosis/handle_hearing(datum/source, list/hearing_args)
hearing_args[HEARING_RAW_MESSAGE] = target_phrase.Replace(hearing_args[HEARING_RAW_MESSAGE], span_hypnophrase("$1"))
+8 -4
View File
@@ -73,12 +73,16 @@
scan_desc = "extra-sensory paranoia"
gain_text = "<span class='warning'>You feel like something wants to kill you...</span>"
lose_text = "<span class='notice'>You no longer feel eyes on your back.</span>"
var/obj/effect/hallucination/simple/stalker_phantom/stalker
var/obj/effect/client_image_holder/stalker_phantom/stalker
var/close_stalker = FALSE //For heartbeat
/datum/brain_trauma/magic/stalker/Destroy()
QDEL_NULL(stalker)
return ..()
/datum/brain_trauma/magic/stalker/on_gain()
create_stalker()
..()
return ..()
/datum/brain_trauma/magic/stalker/proc/create_stalker()
var/turf/stalker_source = locate(owner.x + pick(-12, 12), owner.y + pick(-12, 12), owner.z) //random corner
@@ -86,7 +90,7 @@
/datum/brain_trauma/magic/stalker/on_lose()
QDEL_NULL(stalker)
..()
return ..()
/datum/brain_trauma/magic/stalker/on_life(delta_time, times_fired)
// Dead and unconscious people are not interesting to the psychic stalker.
@@ -115,7 +119,7 @@
close_stalker = FALSE
..()
/obj/effect/hallucination/simple/stalker_phantom
/obj/effect/client_image_holder/stalker_phantom
name = "???"
desc = "It's coming closer..."
image_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi'
+14 -12
View File
@@ -8,16 +8,20 @@
name = "Hallucinations"
desc = "Patient suffers constant hallucinations."
scan_desc = "schizophrenia"
gain_text = "<span class='warning'>You feel your grip on reality slipping...</span>"
lose_text = "<span class='notice'>You feel more grounded.</span>"
gain_text = span_warning("You feel your grip on reality slipping...")
lose_text = span_notice("You feel more grounded.")
/datum/brain_trauma/mild/hallucinations/on_life(delta_time, times_fired)
owner.hallucination = min(owner.hallucination + 10, 50)
..()
if(owner.stat != CONSCIOUS || owner.IsSleeping() || owner.IsUnconscious())
return
if(HAS_TRAIT(owner, TRAIT_HALLUCINATION_SUPPRESSED))
return
owner.adjust_hallucinations_up_to(10 SECONDS * delta_time, 100 SECONDS)
/datum/brain_trauma/mild/hallucinations/on_lose()
owner.hallucination = 0
..()
owner.remove_status_effect(/datum/status_effect/hallucination)
return ..()
/datum/brain_trauma/mild/stuttering
name = "Stuttering"
@@ -109,17 +113,15 @@
lose_text = "<span class='warning'>You no longer feel perfectly healthy.</span>"
/datum/brain_trauma/mild/healthy/on_gain()
owner.set_screwyhud(SCREWYHUD_HEALTHY)
..()
owner.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
return ..()
/datum/brain_trauma/mild/healthy/on_life(delta_time, times_fired)
owner.set_screwyhud(SCREWYHUD_HEALTHY) //just in case of hallucinations
owner.adjustStaminaLoss(-2.5 * delta_time) //no pain, no fatigue
..()
/datum/brain_trauma/mild/healthy/on_lose()
owner.set_screwyhud(SCREWYHUD_NONE)
..()
owner.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
return ..()
/datum/brain_trauma/mild/muscle_weakness
name = "Muscle Weakness"
+2 -2
View File
@@ -200,7 +200,7 @@
if(3, 4)
if(high_stress)
to_chat(owner, span_warning("You're going mad with loneliness!"))
owner.hallucination += 30
owner.adjust_hallucinations(60 SECONDS)
else
to_chat(owner, span_warning("You feel really lonely..."))
@@ -307,7 +307,7 @@
scan_desc = "dyslexia"
gain_text = "<span class='warning'>You have trouble reading or writing...</span>"
lose_text = "<span class='notice'>Your suddenly remember how to read and write.</span>"
/datum/brain_trauma/severe/dyslexia/on_gain()
ADD_TRAIT(owner, TRAIT_ILLITERATE, TRAUMA_TRAIT)
..()
+55 -41
View File
@@ -87,61 +87,64 @@
if(!second_turf)
return
var/obj/effect/hallucination/simple/bluespace_stream/first = new(first_turf, owner)
var/obj/effect/hallucination/simple/bluespace_stream/second = new(second_turf, owner)
var/obj/effect/client_image_holder/bluespace_stream/first = new(first_turf, owner)
var/obj/effect/client_image_holder/bluespace_stream/second = new(second_turf, owner)
first.linked_to = second
second.linked_to = first
first.seer = owner
second.seer = owner
/obj/effect/hallucination/simple/bluespace_stream
/obj/effect/client_image_holder/bluespace_stream
name = "bluespace stream"
desc = "You see a hidden pathway through bluespace..."
image_icon = 'icons/effects/effects.dmi'
image_state = "bluestream"
image_layer = ABOVE_MOB_LAYER
image_plane = GAME_PLANE_UPPER
var/obj/effect/hallucination/simple/bluespace_stream/linked_to
var/mob/living/carbon/seer
var/obj/effect/client_image_holder/bluespace_stream/linked_to
/obj/effect/hallucination/simple/bluespace_stream/Initialize(mapload)
/obj/effect/client_image_holder/bluespace_stream/Initialize(mapload, list/mobs_which_see_us)
. = ..()
QDEL_IN(src, 300)
QDEL_IN(src, 30 SECONDS)
/obj/effect/hallucination/simple/bluespace_stream/Destroy()
/obj/effect/client_image_holder/bluespace_stream/Destroy()
if(!QDELETED(linked_to))
qdel(linked_to)
linked_to = null
seer = null
return ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/effect/hallucination/simple/bluespace_stream/attack_hand(mob/user, list/modifiers)
if(user != seer || !linked_to)
/obj/effect/client_image_holder/bluespace_stream/attack_hand(mob/user, list/modifiers)
. = ..()
if(.)
return
if(!(user in who_sees_us) || !linked_to)
return
var/slip_in_message = pick("slides sideways in an odd way, and disappears", "jumps into an unseen dimension",\
"sticks one leg straight out, wiggles [user.p_their()] foot, and is suddenly gone", "stops, then blinks out of reality", \
"is pulled into an invisible vortex, vanishing from sight")
var/slip_out_message = pick("silently fades in", "leaps out of thin air","appears", "walks out of an invisible doorway",\
"slides out of a fold in spacetime")
to_chat(user, span_notice("You try to align with the bluespace stream..."))
if(do_after(user, 20, target = src))
var/turf/source_turf = get_turf(src)
var/turf/destination_turf = get_turf(linked_to)
if(!do_after(user, 2 SECONDS, target = src))
return
new /obj/effect/temp_visual/bluespace_fissure(source_turf)
new /obj/effect/temp_visual/bluespace_fissure(destination_turf)
var/turf/source_turf = get_turf(src)
var/turf/destination_turf = get_turf(linked_to)
user.visible_message(span_warning("[user] [slip_in_message]."), null, null, null, user)
new /obj/effect/temp_visual/bluespace_fissure(source_turf)
new /obj/effect/temp_visual/bluespace_fissure(destination_turf)
if(!do_teleport(user, destination_turf, no_effects = TRUE))
user.visible_message(span_warning("[user] [slip_out_message], ending up exactly where they left."), null, null, null, user)
return
user.visible_message(span_warning("[user] [slip_in_message]."), ignored_mobs = user)
if(do_teleport(user, destination_turf, no_effects = TRUE))
user.visible_message(span_warning("[user] [slip_out_message]."), span_notice("...and find your way to the other side."))
else
user.visible_message(span_warning("[user] [slip_out_message], ending up exactly where they left."), span_notice("...and find yourself where you started?"))
/obj/effect/hallucination/simple/bluespace_stream/attack_tk(mob/user)
/obj/effect/client_image_holder/bluespace_stream/attack_tk(mob/user)
to_chat(user, span_warning("\The [src] actively rejects your mind, and the bluespace energies surrounding it disrupt your telekinesis!"))
return COMPONENT_CANCEL_ATTACK_CHAIN
@@ -353,62 +356,73 @@
gain_text = "<span class='warning'>Justice is coming for you.</span>"
lose_text = "<span class='notice'>You were absolved for your crimes.</span>"
random_gain = FALSE
var/obj/effect/hallucination/simple/securitron/beepsky
/// A ref to our fake beepsky image that we chase the owner with
var/obj/effect/client_image_holder/securitron/beepsky
/datum/brain_trauma/special/beepsky/Destroy()
QDEL_NULL(beepsky)
return ..()
/datum/brain_trauma/special/beepsky/on_gain()
create_securitron()
..()
return ..()
/datum/brain_trauma/special/beepsky/proc/create_securitron()
QDEL_NULL(beepsky)
var/turf/where = locate(owner.x + pick(-12, 12), owner.y + pick(-12, 12), owner.z)
beepsky = new(where, owner)
beepsky.victim = owner
/datum/brain_trauma/special/beepsky/on_lose()
QDEL_NULL(beepsky)
..()
return ..()
/datum/brain_trauma/special/beepsky/on_life()
if(QDELETED(beepsky) || !beepsky.loc || beepsky.z != owner.z)
QDEL_NULL(beepsky)
if(prob(30))
create_securitron()
else
return
if(get_dist(owner, beepsky) >= 10 && prob(20))
QDEL_NULL(beepsky)
create_securitron()
if(owner.stat != CONSCIOUS)
if(prob(20))
owner.playsound_local(beepsky, 'sound/voice/beepsky/iamthelaw.ogg', 50)
return
if(get_dist(owner, beepsky) <= 1)
owner.playsound_local(owner, 'sound/weapons/egloves.ogg', 50)
owner.visible_message(span_warning("[owner]'s body jerks as if it was shocked."), span_userdanger("You feel the fist of the LAW."))
owner.take_bodypart_damage(0,0,rand(40, 70))
QDEL_NULL(beepsky)
if(prob(20) && get_dist(owner, beepsky) <= 8)
owner.playsound_local(beepsky, 'sound/voice/beepsky/criminal.ogg', 40)
..()
/obj/effect/hallucination/simple/securitron
/obj/effect/client_image_holder/securitron
name = "Securitron"
desc = "The LAW is coming."
image_icon = 'icons/mob/silicon/aibots.dmi'
image_state = "secbot-c"
var/victim
/obj/effect/hallucination/simple/securitron/Initialize(mapload)
/obj/effect/client_image_holder/securitron/Initialize(mapload)
. = ..()
name = pick("Officer Beepsky", "Officer Johnson", "Officer Pingsky")
START_PROCESSING(SSfastprocess, src)
/obj/effect/hallucination/simple/securitron/process()
if(prob(60))
forceMove(get_step_towards(src, victim))
if(prob(5))
to_chat(victim, span_name("[name]</span> exclaims, \"<span class='robotic'>Level 10 infraction alert!\""))
/obj/effect/hallucination/simple/securitron/Destroy()
/obj/effect/client_image_holder/securitron/Destroy()
STOP_PROCESSING(SSfastprocess,src)
return ..()
/obj/effect/client_image_holder/securitron/process()
if(prob(40))
return
var/mob/victim = pick(who_sees_us)
forceMove(get_step_towards(src, victim))
if(prob(5))
var/beepskys_cry = "Level 10 infraction alert!"
to_chat(victim, "<span class='name'>[name]</span> exclaims, \"<span class='robotic'>[beepskys_cry]</span>\"")
if(victim.client?.prefs.read_preference(/datum/preference/toggle/enable_runechat))
victim.create_chat_message(src, raw_message = beepskys_cry, spans = list("robotic"))
@@ -61,4 +61,4 @@
to_chat(M, span_userdanger("[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]"))
else
to_chat(M, span_notice("[pick(healthy_messages)]"))
M.hallucination += (45 * power)
M.adjust_hallucinations(90 SECONDS * power)
@@ -57,7 +57,8 @@
M.reagents.remove_reagent(/datum/reagent/toxin/mindbreaker, 5)
if(M.reagents.has_reagent(/datum/reagent/toxin/histamine))
M.reagents.remove_reagent(/datum/reagent/toxin/histamine, 5)
M.hallucination = max(0, M.hallucination - 10)
M.adjust_hallucinations(-20 SECONDS)
if(A.stage >= 5)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3)
+1 -1
View File
@@ -104,7 +104,7 @@
if(DT_PROB(2.5, delta_time) && owner.stat == CONSCIOUS)
owner.emote("scream")
if(prob(25))
owner.hallucination += 20
owner.adjust_hallucinations(40 SECONDS)
//Dwarfism shrinks your body and lets you pass tables.
/datum/mutation/human/dwarfism
+25 -12
View File
@@ -468,28 +468,41 @@
/datum/quirk/insanity
name = "Reality Dissociation Syndrome"
desc = "You suffer from a severe disorder that causes very vivid hallucinations. Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. THIS IS NOT A LICENSE TO GRIEF."
desc = "You suffer from a severe disorder that causes very vivid hallucinations. \
Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. \
THIS IS NOT A LICENSE TO GRIEF."
icon = "grin-tongue-wink"
value = -8
mob_trait = TRAIT_INSANITY
gain_text = "<span class='userdanger'>...</span>"
lose_text = "<span class='notice'>You feel in tune with the world again.</span>"
gain_text = span_userdanger("...")
lose_text = span_notice("You feel in tune with the world again.")
medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations."
hardcore_value = 6
processing_quirk = TRUE
/datum/quirk/insanity/process(delta_time)
if(quirk_holder.stat != CONSCIOUS || quirk_holder.IsSleeping() || quirk_holder.IsUnconscious())
/datum/quirk/insanity/add()
if(!iscarbon(quirk_holder))
return
var/mob/living/carbon/carbon_quirk_holder = quirk_holder
if(DT_PROB(2, delta_time))
quirk_holder.hallucination += rand(10, 25)
// Setup our special RDS mild hallucination.
// Not a unique subtype so not to plague subtypesof,
// also as we inherit the names and values from our quirk.
var/datum/brain_trauma/mild/hallucinations/added_trauma = new()
added_trauma.resilience = TRAUMA_RESILIENCE_ABSOLUTE
added_trauma.name = name
added_trauma.desc = medical_record_text
added_trauma.scan_desc = lowertext(name)
added_trauma.gain_text = null
added_trauma.lose_text = null
/datum/quirk/insanity/post_add() //I don't /think/ we'll need this but for newbies who think "roleplay as insane" = "license to kill" it's probably a good thing to have
carbon_quirk_holder.gain_trauma(added_trauma)
/datum/quirk/insanity/post_add()
if(!quirk_holder.mind || quirk_holder.mind.special_role)
return
to_chat(quirk_holder, "<span class='big bold info'>Please note that your dissociation syndrome does NOT give you the right to attack people or otherwise cause any interference to \
the round. You are not an antagonist, and the rules will treat you the same as other crewmembers.</span>")
// I don't /think/ we'll need this, but for newbies who think "roleplay as insane" = "license to kill",
// it's probably a good thing to have.
to_chat(quirk_holder, "<span class='big bold info'>Please note that your [lowertext(name)] does NOT give you the right to attack people or otherwise cause any interference to \
the round. You are not an antagonist, and the rules will treat you the same as other crewmembers.</span>")
/datum/quirk/social_anxiety
name = "Social Anxiety"
+18 -5
View File
@@ -378,17 +378,30 @@
. = ..()
to_chat(owner, "<span class='reallybig redtext'>RIP AND TEAR</span>")
SEND_SOUND(owner, sound('sound/hallucinations/veryfar_noise.ogg'))
new /datum/hallucination/delusion(owner, forced = TRUE, force_kind = "demon", duration = duration, skip_nearby = FALSE)
chainsaw = new(get_turf(owner))
owner.log_message("entered a blood frenzy", LOG_ATTACK)
ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
owner.cause_hallucination( \
/datum/hallucination/delusion/preset/demon, \
"[id] status effect", \
duration = duration, \
affects_us = FALSE, \
affects_others = TRUE, \
skip_nearby = FALSE, \
play_wabbajack = FALSE, \
)
owner.drop_all_held_items()
chainsaw = new(get_turf(owner))
ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
owner.put_in_hands(chainsaw, forced = TRUE)
chainsaw.attack_self(owner)
owner.reagents.add_reagent(/datum/reagent/medicine/adminordrazine,25)
owner.log_message("entered a blood frenzy", LOG_ATTACK)
owner.reagents.add_reagent(/datum/reagent/medicine/adminordrazine, 25)
to_chat(owner, span_warning("KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!"))
var/datum/client_colour/colour = owner.add_client_colour(/datum/client_colour/bloodlust)
QDEL_IN(colour, 1.1 SECONDS)
return TRUE
/datum/status_effect/mayhem/on_remove()
. = ..()
@@ -0,0 +1,91 @@
/// Hallucination status effect. How most hallucinations end up happening.
/// Hallucinations are drawn from the global weighted list, random_hallucination_weighted_list
/datum/status_effect/hallucination
id = "hallucination"
alert_type = null
tick_interval = 2 SECONDS
/// Can this hallucination apply to silicons?
var/affects_silicons = FALSE
/// The lower range of when the next hallucination will trigger after one occurs.
var/lower_tick_interval = 10 SECONDS
/// The upper range of when the next hallucination will trigger after one occurs.
var/upper_tick_interval = 60 SECONDS
/// The cooldown for when the next hallucination can occur
COOLDOWN_DECLARE(hallucination_cooldown)
/datum/status_effect/hallucination/on_creation(
mob/living/new_owner,
duration = 10 SECONDS,
affects_silicons = FALSE,
)
src.duration = duration
src.affects_silicons = affects_silicons
return ..()
/datum/status_effect/hallucination/on_apply()
if(!affects_silicons && issilicon(owner))
return FALSE
RegisterSignal(owner, COMSIG_LIVING_POST_FULLY_HEAL, .proc/remove_hallucinations)
RegisterSignal(owner, COMSIG_LIVING_HEALTHSCAN, .proc/on_health_scan)
if(iscarbon(owner))
RegisterSignal(owner, COMSIG_CARBON_CHECKING_BODYPART, .proc/on_check_bodypart)
RegisterSignal(owner, COMSIG_CARBON_BUMPED_AIRLOCK_OPEN, .proc/on_bump_airlock)
return TRUE
/datum/status_effect/hallucination/on_remove()
UnregisterSignal(owner, list(
COMSIG_LIVING_POST_FULLY_HEAL,
COMSIG_LIVING_HEALTHSCAN,
COMSIG_CARBON_CHECKING_BODYPART,
COMSIG_CARBON_BUMPED_AIRLOCK_OPEN,
))
/// Signal proc for [COMSIG_LIVING_POST_FULLY_HEAL], terminate on full heal
/datum/status_effect/hallucination/proc/remove_hallucinations(datum/source)
SIGNAL_HANDLER
qdel(src)
/// Signal proc for [COMSIG_LIVING_HEALTHSCAN]. Show we're hallucinating to (advanced) scanners.
/datum/status_effect/hallucination/proc/on_health_scan(datum/source, list/render_list, advanced, mob/user, mode)
SIGNAL_HANDLER
if(!advanced)
return
render_list += "<span class='info ml-1'>Subject is hallucinating.</span>\n"
/// Signal proc for [COMSIG_CARBON_CHECKING_BODYPART],
/// checking bodyparts while hallucinating can cause them to appear more damaged than they are
/datum/status_effect/hallucination/proc/on_check_bodypart(mob/living/carbon/source, obj/item/bodypart/examined, list/check_list, list/limb_damage)
SIGNAL_HANDLER
if(prob(30))
limb_damage[BRUTE] += rand(30, 40)
if(prob(30))
limb_damage[BURN] += rand(30, 40)
/// Signal proc for [COMSIG_CARBON_BUMPED_AIRLOCK_OPEN], bumping an airlock can cause a fake zap.
/// This only happens on airlock bump, future TODO - make this chance roll for attack_hand opening airlocks too
/datum/status_effect/hallucination/proc/on_bump_airlock(mob/living/carbon/source, obj/machinery/door/airlock/bumped)
SIGNAL_HANDLER
// 1% chance to fake a shock.
if(prob(99) || !source.should_electrocute() || bumped.operating)
return
source.cause_hallucination(/datum/hallucination/shock, "hallucinated shock from [bumped]",)
return STOP_BUMP
/datum/status_effect/hallucination/tick(delta_time, times_fired)
if(owner.stat == DEAD)
return
if(!COOLDOWN_FINISHED(src, hallucination_cooldown))
return
var/datum/hallucination/picked_hallucination = pick_weight(GLOB.random_hallucination_weighted_list)
owner.cause_hallucination(picked_hallucination, "[id] status effect")
COOLDOWN_START(src, hallucination_cooldown, rand(lower_tick_interval, upper_tick_interval))
@@ -0,0 +1,58 @@
/**
* Screwy hud status.
*
* Applied to carbons, it will make their health bar look like it's incorrect -
* in crit (SCREWYHUD_CRIT), dead (SCREWYHUD_DEAD), or fully healthy (SCREWYHUD_HEALTHY)
*
* Grouped status effect, so multiple sources can add a screwyhud without
* accidentally removing another source's hud.
*/
/datum/status_effect/grouped/screwy_hud
alert_type = null
/// The priority of this screwyhud over other screwyhuds.
var/priority = -1
/// The icon we override our owner's healths.icon_state with
var/override_icon
/datum/status_effect/grouped/screwy_hud/on_apply()
if(!iscarbon(owner))
return FALSE
RegisterSignal(owner, COMSIG_CARBON_UPDATING_HEALTH_HUD, .proc/on_health_hud_updated)
owner.update_health_hud()
return TRUE
/datum/status_effect/grouped/screwy_hud/on_remove()
UnregisterSignal(owner, COMSIG_CARBON_UPDATING_HEALTH_HUD)
owner.update_health_hud()
/datum/status_effect/grouped/screwy_hud/proc/on_health_hud_updated(mob/living/carbon/source, shown_health_amount)
SIGNAL_HANDLER
// Shouldn't even be running if we're dead, but just in case...
if(source.stat == DEAD)
return
// It's entirely possible we have multiple screwy huds on one mob.
// Defer to priority to determine which to show. If our's is lower, don't show it.
for(var/datum/status_effect/grouped/screwy_hud/other_screwy_hud in source.status_effects)
if(other_screwy_hud.priority > priority)
return
source.hud_used.healths.icon_state = override_icon
return COMPONENT_OVERRIDE_HEALTH_HUD
/datum/status_effect/grouped/screwy_hud/fake_dead
id = "fake_hud_dead"
priority = 100 // death is absolute
override_icon = "health7"
/datum/status_effect/grouped/screwy_hud/fake_crit
id = "fake_hud_crit"
priority = 90 // crit is almost death, and death is absolute
override_icon = "health6"
/datum/status_effect/grouped/screwy_hud/fake_healthy
id = "fake_hud_healthy"
priority = 10 // fully healthy is the opposite of death, which is absolute
override_icon = "health0"
+9 -2
View File
@@ -161,8 +161,15 @@ GLOBAL_LIST_INIT(voice_of_god_commands, init_voice_of_god_commands())
trigger = "see\\s*the\\s*truth|hallucinate"
/datum/voice_of_god_command/hallucinate/execute(list/listeners, mob/living/user, power_multiplier = 1, message)
for(var/mob/living/carbon/target in listeners)
new /datum/hallucination/delusion(target, TRUE, null, 150 * power_multiplier, 0)
for(var/mob/living/target in listeners)
target.cause_hallucination( \
get_random_valid_hallucination_subtype(/datum/hallucination/delusion/preset), \
"voice of god", \
duration = 15 SECONDS * power_multiplier, \
affects_us = FALSE, \
affects_others = TRUE, \
skip_nearby = FALSE, \
)
/// This command wakes up the listeners.
/datum/voice_of_god_command/wake_up