Files
ZergspowerandGitHub 27551e1caf Tweaks blindness to be more player friendly (#94323)
## About The Pull Request

So something i missed from when i played Goonstation a long while ago
was my blind characters, i tried recreating them in TGCode but found
that the blind quirk here is far more harsh to play visually. So i got
some help from Melbert and got a plan goin and here's the results.


![blinds](https://github.com/user-attachments/assets/d12bd5c1-e0cb-4997-835f-279076c6a665)

Players can see colors! But muted, this change is strictly for visual
enjoyment as the constant monochrome is just - i cant really describe
how much i hate seeing it for more than 15 minutes.

Secondly the flicker is gone from the quirk but remains for all the
temporary blindness, this is 100% Melberts code as they're a helluva lot
smarter than I am and I just nod and smile before pasting it. This did
entail creating a new fulscreen in the dmi, but i just copy/pasted the
existing one and took out the animated frames and named it as 'static'
so it wouldnt interfere with anything else using it.

## Why It's Good For The Game

Playing a blind character is great, however it causes some serious
eyestrain after prolonged playstyle

## Changelog
🆑 MrMelbert, Zergspower
qol: The world is now heavily desaturated while blind, rather than pure
monochrome, to give players some visual stimulus
qol: When blind, the brief flicker of the entire screen now only appears
for mobs temporarily blinded - ie, mobs blinded from quirk / trauma /
genetic mutation no longer experience it
/🆑
2025-12-10 20:42:56 +00:00

122 lines
4.1 KiB
Plaintext

/// Helper macro, for ease of expanding checks for mobs which cannot be blinded
/// There are no reason why these cannot be blinded, it is simply for "design reasons" (these things shouldn't be blinded)
#define CAN_BE_BLIND(mob) (!isanimal_or_basicmob(mob) && !isbrain(mob) && !isrevenant(mob))
/// Blindness
/datum/status_effect/grouped/blindness
// This is not "remove on fullheal" as in practice,
// fullheal should instead remove all the sources and in turn cure this
id = "blindness"
tick_interval = STATUS_EFFECT_NO_TICK
alert_type = /atom/movable/screen/alert/status_effect/blind
var/static/list/update_signals = list(
SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS),
SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS),
)
/// List of sources which prevent SIGHT_BYPASS from working
var/static/list/blocking_sources = list(
QUIRK_TRAIT, // Meant to be completely immutable
ECHOLOCATION_TRAIT, // Breaks the UI badly
UNCONSCIOUS_TRAIT, // Duh
)
/datum/status_effect/grouped/blindness/on_apply()
if (!CAN_BE_BLIND(owner))
return FALSE
RegisterSignals(owner, update_signals, PROC_REF(update_blindness))
return ..()
/datum/status_effect/grouped/blindness/source_added(source, ...)
update_blindness(source)
/datum/status_effect/grouped/blindness/source_removed(source, removing)
if (!removing)
update_blindness(source)
/datum/status_effect/grouped/blindness/proc/update_blindness(changed_source)
if (!CAN_BE_BLIND(owner)) // future proofing
qdel(src)
return
if (!HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS))
make_blind(changed_source)
return
for (var/blocker in blocking_sources)
if (owner.is_blind_from(blocker))
make_blind(changed_source)
return
make_unblind()
/datum/status_effect/grouped/blindness/proc/make_blind(changed_source)
// have some extra logic to determine what overlay to use
// by default we use the noflicker overlay
// but if our one and only source is from "temp blindness", use flicker overlay
var/overlay_to_use = /atom/movable/screen/fullscreen/blind/noflicker
if(changed_source == /datum/status_effect/temporary_blindness::id && length(sources) == 1)
overlay_to_use = /atom/movable/screen/fullscreen/blind
owner.overlay_fullscreen(id, overlay_to_use )
// You are blind - at most, able to make out shapes near you
owner.add_client_colour(/datum/client_colour/blindness, REF(src))
/datum/status_effect/grouped/blindness/proc/make_unblind()
owner.clear_fullscreen(id)
owner.remove_client_colour(REF(src))
/datum/status_effect/grouped/blindness/on_remove()
make_unblind()
UnregisterSignal(owner, update_signals)
return ..()
/atom/movable/screen/alert/status_effect/blind
name = "Blind"
desc = "You can't see! This may be caused by a genetic defect, eye trauma, being unconscious, or something covering your eyes."
use_user_hud_icon = TRUE
overlay_state = "blind"
/// This status effect handles applying a temporary blind to the mob.
/datum/status_effect/temporary_blindness
id = "temporary_blindness"
tick_interval = 2 SECONDS
alert_type = null
remove_on_fullheal = TRUE
/datum/status_effect/temporary_blindness/on_creation(mob/living/new_owner, duration = 10 SECONDS)
src.duration = duration
return ..()
/datum/status_effect/temporary_blindness/on_apply()
if(!CAN_BE_BLIND(owner))
return FALSE
owner.become_blind(id)
return TRUE
/datum/status_effect/temporary_blindness/on_remove()
owner.cure_blind(id)
/datum/status_effect/temporary_blindness/tick(seconds_between_ticks)
if(owner.stat == DEAD)
return
// Temp. blindness heals faster if our eyes are covered
if(!owner.is_blind_from(EYES_COVERED))
return
// Knocks 2 seconds off of our duration
// If we should be deleted, give a message letting them know
var/mob/living/stored_owner = owner
if(remove_duration(2 SECONDS))
to_chat(stored_owner, span_green("Your eyes start to feel better!"))
return
// Otherwise add a chance to let them know that it's working
else if(SPT_PROB(5, seconds_between_ticks))
var/obj/item/thing_covering_eyes = owner.is_eyes_covered()
// "Your blindfold soothes your eyes", for example
to_chat(owner, span_green("Your [thing_covering_eyes?.name || "eye covering"] soothes your eyes."))
#undef CAN_BE_BLIND