[MIRROR] Converts blindness and nearsightedness to status effects, scratches some VERY dumb blindness handling that resulted in mobs becoming "incurably" blind [MDB IGNORE] (#18760)

* Converts blindness and nearsightedness to status effects, scratches some VERY dumb blindness handling that resulted in mobs becoming "incurably" blind

* Fixes the conflicts and makes shit compile!

* Fixes other things that didn't show up because I hadn't updated

* Fixes the lints.

* Okay NOW it's ready (please don't add anything else that touches blindness I beg you)

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
This commit is contained in:
SkyratBot
2023-02-03 16:08:32 -05:00
committed by GitHub
co-authored by MrMelbert GoldenAlpharex
parent bc6b643082
commit 1fe0d145a3
88 changed files with 850 additions and 654 deletions
-1
View File
@@ -16,7 +16,6 @@
/** Mob related */
#define ALERT_SUCCUMB "succumb"
#define ALERT_BLIND "blind"
#define ALERT_BUCKLED "buckled"
#define ALERT_HANDCUFFED "handcuffed"
#define ALERT_LEGCUFFED "legcuffed"
+36
View File
@@ -39,6 +39,34 @@
#define STASIS_SHAPECHANGE_EFFECT "stasis_shapechange"
/// Causes the mob to become blind via the passed source
#define become_blind(source) apply_status_effect(/datum/status_effect/grouped/blindness, source)
/// Cures the mob's blindness from the passed source, removing blindness wholesale if no sources are left
#define cure_blind(source) remove_status_effect(/datum/status_effect/grouped/blindness, source)
/// Is the mob blind?
#define is_blind(...) has_status_effect(/datum/status_effect/grouped/blindness)
/// Is the mob blind from the passed source or sources?
#define is_blind_from(sources) has_status_effect_from_source(/datum/status_effect/grouped/blindness, sources)
/// Causes the mob to become nearsighted via the passed source
#define become_nearsighted(source) apply_status_effect(/datum/status_effect/grouped/nearsighted, source)
/// Cures the mob's nearsightedness from the passed source, removing nearsighted wholesale if no sources are left
#define cure_nearsighted(source) remove_status_effect(/datum/status_effect/grouped/nearsighted, source)
/// Is the mob nearsighted?
#define is_nearsighted(...) has_status_effect(/datum/status_effect/grouped/nearsighted)
/// Is the mob nearsigthed from the passed source or sources?
#define is_nearsighted_from(sources) has_status_effect_from_source(/datum/status_effect/grouped/nearsighted, sources)
/// Is the mob nearsighted CURRENTLY?
/// This check fails if the mob is nearsighted but is wearing glasses,
/// While is_nearsighted will always succeed even if they are wearing glasses.
/mob/proc/is_nearsighted_currently()
var/datum/status_effect/grouped/nearsighted/nearsight = has_status_effect(/datum/status_effect/grouped/nearsighted)
if(isnull(nearsight))
return FALSE
return nearsight.should_be_nearsighted()
// Status effect application helpers.
// These are macros for easier use of adjust_timed_status_effect and set_timed_status_effect.
//
@@ -114,7 +142,15 @@
#define set_drowsiness(duration) set_timed_status_effect(duration, /datum/status_effect/drowsiness)
#define set_drowsiness_if_lower(duration) set_timed_status_effect(duration, /datum/status_effect/drowsiness, TRUE)
#define adjust_pacifism(duration) adjust_timed_status_effect(/datum/status_effect/pacify, duration)
#define set_pacifism(duration) set_timed_status_effect(/datum/status_effect/pacify, duration)
#define adjust_eye_blur(duration) adjust_timed_status_effect(duration, /datum/status_effect/eye_blur)
#define adjust_eye_blur_up_to(duration, up_to) adjust_timed_status_effect(duration, /datum/status_effect/eye_blur, up_to)
#define set_eye_blur(duration) set_timed_status_effect(duration, /datum/status_effect/eye_blur)
#define set_eye_blur_if_lower(duration) set_timed_status_effect(duration, /datum/status_effect/eye_blur, TRUE)
#define adjust_temp_blindness(duration) adjust_timed_status_effect(duration, /datum/status_effect/temporary_blindness)
#define adjust_temp_blindness_up_to(duration, up_to) adjust_timed_status_effect(duration, /datum/status_effect/temporary_blindness, up_to)
#define set_temp_blindness(duration) set_timed_status_effect(duration, /datum/status_effect/temporary_blindness)
#define set_temp_blindness_if_lower(duration) set_timed_status_effect(duration, /datum/status_effect/temporary_blindness, TRUE)
+3 -6
View File
@@ -144,7 +144,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_LITERATE "literate"
/// Blacklist for mobs that can't read or write
#define TRAIT_ILLITERATE "illiterate"
#define TRAIT_BLIND "blind"
/// Mute. Can't talk.
#define TRAIT_MUTE "mute"
/// Gibs on death and slips like ice.
@@ -152,7 +151,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Emotemute. Can't... emote.
#define TRAIT_EMOTEMUTE "emotemute"
#define TRAIT_DEAF "deaf"
#define TRAIT_NEARSIGHT "nearsighted"
#define TRAIT_FAT "fat"
#define TRAIT_HUSK "husk"
///Blacklisted from being revived via defibrilator
@@ -298,6 +296,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_QUICK_BUILD "quick-build"
/// We can handle 'dangerous' plants in botany safely
#define TRAIT_PLANT_SAFE "plant_safe"
/// Prevents the overlay from nearsighted
#define TRAIT_NEARSIGHTED_CORRECTED "fixes_nearsighted"
#define TRAIT_UNINTELLIGIBLE_SPEECH "unintelligible-speech"
#define TRAIT_UNSTABLE "unstable"
#define TRAIT_OIL_FRIED "oil_fried"
@@ -799,16 +799,15 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define CHANGELING_DRAIN "drain"
/// changelings with this trait can no longer talk over the hivemind
#define CHANGELING_HIVEMIND_MUTE "ling_mute"
#define ABYSSAL_GAZE_BLIND "abyssal_gaze"
#define HIGHLANDER "highlander"
#define TRAIT_HULK "hulk"
#define STASIS_MUTE "stasis"
#define GENETICS_SPELL "genetics_spell"
#define EYES_COVERED "eyes_covered"
#define NO_EYES "no_eyes"
#define HYPNOCHAIR_TRAIT "hypnochair"
#define FLASHLIGHT_EYES "flashlight_eyes"
#define IMPURE_OCULINE "impure_oculine"
#define BLINDFOLD_TRAIT "blindfolded"
#define TRAIT_SANTA "santa"
#define SCRYING_ORB "scrying-orb"
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
@@ -891,8 +890,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define ORBITING_TRAIT "orbiting"
/// From the item_scaling element
#define ITEM_SCALING_TRAIT "item_scaling"
/// Trait given by Objects that provide blindsight
#define ITEM_BLIND_TRAIT "blind_item_trait"
/// Trait given by choking
#define CHOKING_TRAIT "choking_trait"
/// Trait given by hallucinations
-2
View File
@@ -18,11 +18,9 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_LITERATE" = TRAIT_LITERATE,
"TRAIT_ILLITERATE" = TRAIT_ILLITERATE,
"TRAIT_BLIND" = TRAIT_BLIND,
"TRAIT_MUTE" = TRAIT_MUTE,
"TRAIT_EMOTEMUTE " = TRAIT_EMOTEMUTE,
"TRAIT_DEAF" = TRAIT_DEAF,
"TRAIT_NEARSIGHT" = TRAIT_NEARSIGHT,
"TRAIT_FAT" = TRAIT_FAT,
"TRAIT_HUSK" = TRAIT_HUSK,
"TRAIT_DEFIB_BLACKLISTED" = TRAIT_DEFIB_BLACKLISTED,
-6
View File
@@ -230,12 +230,6 @@
desc = "The air around you is hazardously thick. A fire suit would protect you."
icon_state = "highpressure"
/atom/movable/screen/alert/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."
icon_state = ALERT_BLIND
/atom/movable/screen/alert/hypnosis
name = "Hypnosis"
desc = "Something's hypnotizing you, but you're not really sure about what."
+1 -1
View File
@@ -121,7 +121,7 @@
if(3)
to_chat(owner, span_warning("You shut your eyes in terror!"))
owner.set_jitter_if_lower(10 SECONDS)
owner.adjust_blindness(10)
owner.adjust_temp_blindness(20 SECONDS)
if(4)
owner.adjust_dizzy(20 SECONDS)
owner.adjust_confusion(10 SECONDS)
+2 -2
View File
@@ -451,9 +451,9 @@ Behavior that's still missing from this component that original food items had t
return FALSE
var/mob/living/carbon/C = eater
var/covered = ""
if(C.is_mouth_covered(head_only = 1))
if(C.is_mouth_covered(ITEM_SLOT_HEAD))
covered = "headgear"
else if(C.is_mouth_covered(mask_only = 1))
else if(C.is_mouth_covered(ITEM_SLOT_MASK))
covered = "mask"
if(covered)
var/who = (isnull(feeder) || eater == feeder) ? "your" : "[eater.p_their()]"
+1 -1
View File
@@ -135,7 +135,7 @@
span_boldwarning("Your [affected_limb.plaintext_zone] bubbles unnaturally, then bursts into blisters!"),
)
if (human_parent.is_blind())
if(human_parent.is_blind())
to_chat(human_parent, span_boldwarning("Your [affected_limb.plaintext_zone] feels like it's bubbling, then burns like hell!"))
human_parent.apply_damage(RADIATION_BURN_SPLOTCH_DAMAGE, BURN, affected_limb)
@@ -84,32 +84,34 @@
symptom_delay_min = 1
symptom_delay_max = 1
/datum/symptom/sensory_restoration/Activate(datum/disease/advance/A)
/datum/symptom/sensory_restoration/Activate(datum/disease/advance/source_disease)
. = ..()
if(!.)
return
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
var/mob/living/carbon/ill_mob = source_disease.affected_mob
switch(source_disease.stage)
if(4, 5)
var/obj/item/organ/internal/ears/ears = M.getorganslot(ORGAN_SLOT_EARS)
var/obj/item/organ/internal/ears/ears = ill_mob.getorganslot(ORGAN_SLOT_EARS)
if(ears)
ears.adjustEarDamage(-4, -4)
M.adjust_blindness(-2)
M.adjust_eye_blur(-4 SECONDS)
var/obj/item/organ/internal/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
ill_mob.adjust_temp_blindness(-4 SECONDS)
ill_mob.adjust_eye_blur(-4 SECONDS)
var/obj/item/organ/internal/eyes/eyes = ill_mob.getorganslot(ORGAN_SLOT_EYES)
if(!eyes) // only dealing with eye stuff from here on out
return
eyes.applyOrganDamage(-2)
if(HAS_TRAIT_FROM(M, TRAIT_BLIND, EYE_DAMAGE))
if(prob(20))
to_chat(M, span_warning("Your vision slowly returns..."))
M.cure_blind(EYE_DAMAGE)
M.cure_nearsighted(EYE_DAMAGE)
M.set_eye_blur_if_lower(70 SECONDS)
else if(HAS_TRAIT_FROM(M, TRAIT_NEARSIGHT, EYE_DAMAGE))
to_chat(M, span_warning("The blackness in your peripheral vision fades."))
M.cure_nearsighted(EYE_DAMAGE)
M.set_eye_blur_if_lower(20 SECONDS)
if(prob(20))
if(ill_mob.is_blind_from(EYE_DAMAGE))
to_chat(ill_mob, span_warning("Your vision slowly returns..."))
ill_mob.adjust_eye_blur(20 SECONDS)
else if(ill_mob.is_nearsighted_from(EYE_DAMAGE))
to_chat(ill_mob, span_warning("The blackness in your peripheral vision begins to fade."))
ill_mob.adjust_eye_blur(5 SECONDS)
else
if(prob(base_message_chance))
to_chat(M, span_notice("[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your hearing feels more acute.")]"))
to_chat(ill_mob, span_notice("[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your hearing feels more acute.")]"))
+41 -28
View File
@@ -18,12 +18,14 @@
base_message_chance = 50
symptom_delay_min = 25
symptom_delay_max = 80
var/remove_eyes = FALSE
threshold_descs = list(
"Resistance 12" = "Weakens extraocular muscles, eventually leading to complete detachment of the eyes.",
"Stealth 4" = "The symptom remains hidden until active.",
)
/// At max stage: If FALSE, cause blindness. If TRUE, cause their eyes to fall out.
var/remove_eyes = FALSE
/datum/symptom/visionloss/Start(datum/disease/advance/A)
. = ..()
if(!.)
@@ -33,34 +35,45 @@
if(A.totalResistance() >= 12) //goodbye eyes
remove_eyes = TRUE
/datum/symptom/visionloss/Activate(datum/disease/advance/A)
/datum/symptom/visionloss/Activate(datum/disease/advance/source_disease)
. = ..()
if(!.)
return
var/mob/living/carbon/M = A.affected_mob
var/obj/item/organ/internal/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
if(eyes)
switch(A.stage)
if(1, 2)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, span_warning("Your eyes itch."))
if(3, 4)
to_chat(M, span_boldwarning("Your eyes burn!"))
M.set_eye_blur_if_lower(20 SECONDS)
eyes.applyOrganDamage(1)
var/mob/living/carbon/ill_mob = source_disease.affected_mob
var/obj/item/organ/internal/eyes/eyes = ill_mob.getorganslot(ORGAN_SLOT_EYES)
if(!eyes)
return // can't do much
switch(source_disease.stage)
if(1, 2)
if(prob(base_message_chance) && !suppress_warning)
to_chat(ill_mob, span_warning("Your eyes itch."))
if(3, 4)
to_chat(ill_mob, span_boldwarning("Your eyes burn!"))
ill_mob.set_eye_blur_if_lower(20 SECONDS)
eyes.applyOrganDamage(1)
else
ill_mob.set_eye_blur_if_lower(40 SECONDS)
eyes.applyOrganDamage(5)
// Applies nearsighted at minimum
if(!ill_mob.is_nearsighted_from(EYE_DAMAGE) && eyes.damage <= eyes.low_threshold)
eyes.setOrganDamage(eyes.low_threshold)
if(prob(eyes.damage - eyes.low_threshold + 1))
if(remove_eyes)
ill_mob.visible_message(
span_warning("[ill_mob]'s eyes fall out of their sockets!"),
span_userdanger("Your eyes fall out of their sockets!"),
)
eyes.Remove(ill_mob)
eyes.forceMove(get_turf(ill_mob))
else if(!ill_mob.is_blind_from(EYE_DAMAGE))
to_chat(ill_mob, span_userdanger("You go blind!"))
eyes.applyOrganDamage(eyes.maxHealth)
else
M.set_eye_blur_if_lower(40 SECONDS)
eyes.applyOrganDamage(5)
if(eyes.damage >= 10)
M.become_nearsighted(EYE_DAMAGE)
if(prob(eyes.damage - 10 + 1))
if(!remove_eyes)
if(!M.is_blind())
to_chat(M, span_userdanger("You go blind!"))
eyes.applyOrganDamage(eyes.maxHealth)
else
M.visible_message(span_warning("[M]'s eyes fall out of their sockets!"), span_userdanger("Your eyes fall out of their sockets!"))
eyes.Remove(M)
eyes.forceMove(get_turf(M))
else
to_chat(M, span_userdanger("Your eyes burn horrifically!"))
to_chat(ill_mob, span_userdanger("Your eyes burn horrifically!"))
+32 -18
View File
@@ -1,5 +1,9 @@
/// What's the probability a clumsy person stabs themselves in the eyes?
#define CLUMSY_ATTACK_SELF_CHANCE 50
/// The damage threshold (of the victim's eyes) after which they start taking more serious effects
#define EYESTAB_BLEEDING_THRESHOLD 10
/// How much blur we can apply
#define EYESTAB_MAX_BLUR (4 MINUTES)
/// An element that lets you stab people in the eyes when targeting them
/datum/element/eyestab
@@ -28,13 +32,18 @@
/datum/element/eyestab/proc/on_item_attack(datum/source, mob/living/target, mob/living/user)
SIGNAL_HANDLER
if (user.zone_selected == BODY_ZONE_PRECISE_EYES)
if (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(CLUMSY_ATTACK_SELF_CHANCE))
target = user
if (user.zone_selected != BODY_ZONE_PRECISE_EYES)
return
perform_eyestab(source, target, user)
if (HAS_TRAIT(user, TRAIT_PACIFISM))
return
return COMPONENT_SKIP_ATTACK
if (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(CLUMSY_ATTACK_SELF_CHANCE))
target = user
perform_eyestab(source, target, user)
return COMPONENT_SKIP_ATTACK
/datum/element/eyestab/proc/perform_eyestab(obj/item/item, mob/living/target, mob/living/user)
var/obj/item/bodypart/target_limb = target.get_bodypart(BODY_ZONE_HEAD)
@@ -84,31 +93,36 @@
if (!eyes)
return
target.adjust_eye_blur(6 SECONDS)
eyes.applyOrganDamage(rand(2,4))
target.adjust_eye_blur_up_to(6 SECONDS, EYESTAB_MAX_BLUR)
eyes.applyOrganDamage(rand(2, 4))
if(eyes.damage < EYESTAB_BLEEDING_THRESHOLD)
return
target.adjust_eye_blur(30 SECONDS)
// At over 10 damage we apply a lot of eye blur
target.adjust_eye_blur_up_to(30 SECONDS, EYESTAB_MAX_BLUR)
if (target.stat != DEAD)
to_chat(target, span_danger("Your eyes start to bleed profusely!"))
if (!target.is_blind() && !HAS_TRAIT(target, TRAIT_NEARSIGHT))
to_chat(target, span_danger("You become nearsighted!"))
target.become_nearsighted(EYE_DAMAGE)
// At over 10 damage, we cause at least enough eye damage to force nearsightedness
if (!target.is_nearsighted_from(EYE_DAMAGE) && eyes.damage <= eyes.low_threshold)
eyes.setOrganDamage(eyes.low_threshold)
// At over 10 damage, there is a 50% chance they drop all their items
if (prob(50))
if (target.stat != DEAD && target.drop_all_held_items())
to_chat(target, span_danger("You drop what you're holding and clutch at your eyes!"))
target.adjust_eye_blur(20 SECONDS)
target.Unconscious(20)
target.Paralyze(40)
target.adjust_eye_blur_up_to(20 SECONDS, EYESTAB_MAX_BLUR)
target.Unconscious(2 SECONDS)
target.Paralyze(4 SECONDS)
if (prob(eyes.damage - EYESTAB_BLEEDING_THRESHOLD + 1))
target.become_blind(EYE_DAMAGE)
to_chat(target, span_danger("You go blind!"))
// At over 10 damage, there is a chance (based on eye damage) of going blind
if (prob(eyes.damage - eyes.low_threshold + 1))
if (!target.is_blind_from(EYE_DAMAGE))
eyes.setOrganDamage(eyes.maxHealth)
// Also cause some temp blindness, so that they're still blind even if they get healed
target.adjust_temp_blindness_up_to(20 SECONDS, 1 MINUTES)
#undef CLUMSY_ATTACK_SELF_CHANCE
#undef EYESTAB_BLEEDING_THRESHOLD
#undef EYESTAB_MAX_BLUR
+1 -1
View File
@@ -67,6 +67,6 @@
if(isliving(examiner) && prob(20))
var/mob/living/target = examiner
examine_text += span_danger("You can feel something in [eaten_light.p_them()] gnash at your eyes!")
target.adjust_blindness(5)
target.adjust_temp_blindness(10 SECONDS)
target.set_eye_blur_if_lower(20 SECONDS)
return NONE
+11 -11
View File
@@ -492,19 +492,19 @@
qdel(I)
explosion(owner, light_impact_range = 2, adminlog = TRUE, explosion_cause = src)
for(var/mob/living/carbon/human/H in view(2,owner))
var/obj/item/organ/internal/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
for(var/mob/living/carbon/human/splashed in view(2, owner))
var/obj/item/organ/internal/eyes/eyes = splashed.getorganslot(ORGAN_SLOT_EYES)
if(eyes)
to_chat(H, span_userdanger("You are blinded by a shower of blood!"))
to_chat(splashed, span_userdanger("You are blinded by a shower of blood!"))
eyes.applyOrganDamage(5)
else
to_chat(H, span_userdanger("You are knocked down by a wave of... blood?!"))
H.Stun(20)
H.set_eye_blur_if_lower(40 SECONDS)
eyes?.applyOrganDamage(5)
H.adjust_confusion(3 SECONDS)
for(var/mob/living/silicon/S in view(2,owner))
to_chat(S, span_userdanger("Your sensors are disabled by a shower of blood!"))
S.Paralyze(60)
to_chat(splashed, span_userdanger("You are knocked down by a wave of... blood?!"))
splashed.Stun(2 SECONDS)
splashed.set_eye_blur_if_lower(40 SECONDS)
splashed.adjust_confusion(3 SECONDS)
for(var/mob/living/silicon/borgo in view(2, owner))
to_chat(borgo, span_userdanger("Your sensors are disabled by a shower of blood!"))
borgo.Paralyze(6 SECONDS)
owner.investigate_log("has been gibbed by the martyrdom mutation.", INVESTIGATE_DEATHS)
owner.gib()
@@ -69,7 +69,13 @@
*
* Returns an instance of a status effect, or NULL if none were found.
*/
/mob/living/proc/has_status_effect(datum/status_effect/checked_effect)
/mob/proc/has_status_effect(datum/status_effect/checked_effect)
// Yes I'm being cringe and putting this on the mob level even though status effects only apply to the living level
// There's quite a few places (namely examine and, bleh, cult code) where it's easier to not need to cast to living before checking
// for an effect such as blindness
return null
/mob/living/has_status_effect(datum/status_effect/checked_effect)
RETURN_TYPE(/datum/status_effect)
for(var/datum/status_effect/present_effect as anything in status_effects)
@@ -78,6 +84,36 @@
return null
/**
* Checks if this mob has a status effect that shares the passed effect's ID
* and has the passed sources are in its list of sources (ONLY works for grouped efects!)
*
* checked_effect - TYPEPATH of a status effect to check for. Checks for its ID, not it's typepath
*
* Returns an instance of a status effect, or NULL if none were found.
*/
/mob/proc/has_status_effect_from_source(datum/status_effect/grouped/checked_effect, sources)
// See [/mob/proc/has_status_effect] for reason behind having this on the mob level
return null
/mob/living/has_status_effect_from_source(datum/status_effect/grouped/checked_effect, sources)
RETURN_TYPE(/datum/status_effect)
if(!ispath(checked_effect))
CRASH("has_status_effect_from_source passed with an improper status effect path.")
if(!islist(sources))
sources = list(sources)
for(var/datum/status_effect/grouped/present_effect in status_effects)
if(present_effect.id != initial(checked_effect.id))
continue
var/list/matching_sources = present_effect.sources & sources
if(length(matching_sources))
return present_effect
return null
/**
* Returns a list of all status effects that share the passed effect type's ID
*
@@ -85,7 +121,11 @@
*
* Returns a list
*/
/mob/living/proc/has_status_effect_list(datum/status_effect/checked_effect)
/mob/proc/has_status_effect_list(datum/status_effect/checked_effect)
// See [/mob/proc/has_status_effect] for reason behind having this on the mob level
return null
/mob/living/has_status_effect_list(datum/status_effect/checked_effect)
RETURN_TYPE(/list)
var/list/effects_found = list()
@@ -0,0 +1,124 @@
/// 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))
/// Nearsighted
/datum/status_effect/grouped/nearsighted
id = "nearsighted"
tick_interval = -1
alert_type = null
// This is not "remove on fullheal" as in practice,
// fullheal should instead remove all the sources and in turn cure this
/// Static list of signals that, when recieved, we force an update to our nearsighted overlay
var/static/list/update_signals = list(SIGNAL_ADDTRAIT(TRAIT_NEARSIGHTED_CORRECTED), SIGNAL_REMOVETRAIT(TRAIT_NEARSIGHTED_CORRECTED))
/// How severe is our nearsightedness right now
var/overlay_severity = 1
/datum/status_effect/grouped/nearsighted/on_apply()
RegisterSignals(owner, update_signals, PROC_REF(update_nearsightedness))
update_nearsighted_overlay()
return ..()
/datum/status_effect/grouped/nearsighted/on_remove()
UnregisterSignal(owner, update_signals)
owner.clear_fullscreen(id)
return ..()
/// Signal proc for when we gain or lose [TRAIT_NEARSIGHTED_CORRECTED] - (temporarily) disable the overlay if we're correcting it
/datum/status_effect/grouped/nearsighted/proc/update_nearsightedness(datum/source)
SIGNAL_HANDLER
update_nearsighted_overlay()
/// Checks if we should be nearsighted currently, or if we should clear the overlay
/datum/status_effect/grouped/nearsighted/proc/should_be_nearsighted()
return !HAS_TRAIT(owner, TRAIT_NEARSIGHTED_CORRECTED)
/// Updates our nearsightd overlay, either removing it if we have the trait or adding it if we don't
/datum/status_effect/grouped/nearsighted/proc/update_nearsighted_overlay()
if(should_be_nearsighted())
owner.overlay_fullscreen(id, /atom/movable/screen/fullscreen/impaired, overlay_severity)
else
owner.clear_fullscreen(id)
/// Sets the severity of our nearsighted overlay
/datum/status_effect/grouped/nearsighted/proc/set_nearsighted_severity(to_value)
if(!isnum(to_value))
return
if(overlay_severity == to_value)
return
overlay_severity = to_value
update_nearsighted_overlay()
/// Blindness
/datum/status_effect/grouped/blindness
id = "blindness"
tick_interval = -1
alert_type = /atom/movable/screen/alert/status_effect/blind
// This is not "remove on fullheal" as in practice,
// fullheal should instead remove all the sources and in turn cure this
/datum/status_effect/grouped/blindness/on_apply()
if(!CAN_BE_BLIND(owner))
return FALSE
owner.overlay_fullscreen(id, /atom/movable/screen/fullscreen/blind)
// You are blind - at most, able to make out shapes near you
owner.add_client_colour(/datum/client_colour/monochrome/blind)
return ..()
/datum/status_effect/grouped/blindness/on_remove()
owner.clear_fullscreen(id)
owner.remove_client_colour(/datum/client_colour/monochrome/blind)
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."
icon_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(delta_time, times_fired)
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(DT_PROB(5, delta_time))
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
+1 -20
View File
@@ -192,7 +192,7 @@
var/is_sleeping_in_darkness = rest_turf.get_lumcount() <= LIGHTING_TILE_IS_DARK
// sleeping with a blindfold or in the dark helps us rest
if(HAS_TRAIT_FROM(owner, TRAIT_BLIND, BLINDFOLD_TRAIT) || is_sleeping_in_darkness)
if(owner.is_blind_from(EYES_COVERED) || is_sleeping_in_darkness)
healing += 0.1
// sleeping in silence is always better
@@ -296,25 +296,6 @@
desc = "Your biological functions have halted. You could live forever this way, but it's pretty boring."
icon_state = "stasis"
/datum/status_effect/pacify
id = "pacify"
status_type = STATUS_EFFECT_REPLACE
tick_interval = 1
duration = 100
alert_type = null
/datum/status_effect/pacify/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
duration = set_duration
. = ..()
/datum/status_effect/pacify/on_apply()
ADD_TRAIT(owner, TRAIT_PACIFISM, STATUS_EFFECT_TRAIT)
return ..()
/datum/status_effect/pacify/on_remove()
REMOVE_TRAIT(owner, TRAIT_PACIFISM, STATUS_EFFECT_TRAIT)
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
id = "his_wrath"
duration = -1
@@ -0,0 +1,14 @@
/datum/status_effect/pacify
id = "pacify"
alert_type = null
/datum/status_effect/pacify/on_creation(mob/living/new_owner, duration = 10 SECONDS)
src.duration = duration
return ..()
/datum/status_effect/pacify/on_apply()
ADD_TRAIT(owner, TRAIT_PACIFISM, id)
return TRUE
/datum/status_effect/pacify/on_remove()
REMOVE_TRAIT(owner, TRAIT_PACIFISM, id)
+2 -2
View File
@@ -91,7 +91,7 @@
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE)
return
victim = C
if(!(C.get_eye_protection() > 0))
if(C.get_eye_protection() <= 0)
to_chat(C, span_warning("Strobing coloured lights assault you relentlessly! You're losing your ability to think straight!"))
C.become_blind(HYPNOCHAIR_TRAIT)
ADD_TRAIT(C, TRAIT_DEAF, HYPNOCHAIR_TRAIT)
@@ -148,7 +148,7 @@
if(QDELETED(victim))
victim = null
return
victim.cure_blind("hypnochair")
victim.cure_blind(HYPNOCHAIR_TRAIT)
REMOVE_TRAIT(victim, TRAIT_DEAF, HYPNOCHAIR_TRAIT)
if(!(victim.get_eye_protection() > 0))
var/time_diff = world.time - start_time
+3 -3
View File
@@ -437,9 +437,9 @@
if(iscarbon(M))
var/mob/living/carbon/C = M
var/covered = ""
if(C.is_mouth_covered(head_only = 1))
if(C.is_mouth_covered(ITEM_SLOT_HEAD))
covered = "headgear"
else if(C.is_mouth_covered(mask_only = 1))
else if(C.is_mouth_covered(ITEM_SLOT_MASK))
covered = "mask"
if(covered)
to_chat(C, span_warning("You have to remove your [covered] first!"))
@@ -696,7 +696,7 @@
if(C.client)
C.set_eye_blur_if_lower(6 SECONDS)
C.adjust_blindness(1)
C.adjust_temp_blindness(2 SECONDS)
if(C.get_eye_protection() <= 0) // no eye protection? ARGH IT BURNS. Warning: don't add a stun here. It's a roundstart item with some quirks.
C.apply_effects(eyeblur = 5, jitter = 10)
flash_color(C, flash_color=paint_color, flash_time=40)
@@ -217,7 +217,7 @@
if(istype(eyes))
if(carbontarget.is_blind())
render_list += "<span class='alert ml-2'>Subject is blind.\n</span>"
else if(HAS_TRAIT(carbontarget, TRAIT_NEARSIGHT))
else if(carbontarget.is_nearsighted())
render_list += "<span class='alert ml-2'>Subject is nearsighted.\n</span>"
// Body part damage report
@@ -16,7 +16,7 @@
/obj/item/book/granter/action/spell/blind/recoil(mob/living/user)
. = ..()
to_chat(user, span_warning("You go blind!"))
user.adjust_blindness(10)
user.adjust_temp_blindness(20 SECONDS)
/obj/item/book/granter/action/spell/blind/wgw
name = "Woody's Got Wood"
@@ -30,4 +30,3 @@
"Please, make it stop...",
"HELP ME SOMEONE, WHY AM I READING THIS...",
)
+1 -1
View File
@@ -498,7 +498,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
attack_verb_continuous_on = list("smacks", "strikes", "cracks", "beats"), \
attack_verb_simple_on = list("smack", "strike", "crack", "beat"))
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform))
ADD_TRAIT(src, TRAIT_BLIND_TOOL, ITEM_BLIND_TRAIT)
ADD_TRAIT(src, TRAIT_BLIND_TOOL, INNATE_TRAIT)
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
@@ -649,4 +649,3 @@
/obj/structure/displaycase/forsale/kitchen
desc = "A display case with an ID-card swiper. Use your ID to purchase the contents. Meant for the bartender and chef."
req_one_access = list(ACCESS_KITCHEN, ACCESS_BAR)
-13
View File
@@ -120,19 +120,6 @@
log_admin("[key_name(usr)] spawned cargo pack [chosen] at [AREACOORD(usr)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Cargo") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggletintedweldhelmets()
set category = "Debug"
set desc="Reduces view range when wearing welding helmets"
set name="Toggle tinted welding helmes"
GLOB.tinted_weldhelh = !( GLOB.tinted_weldhelh )
if (GLOB.tinted_weldhelh)
to_chat(world, "<B>The tinted_weldhelh has been enabled!</B>", confidential = TRUE)
else
to_chat(world, "<B>The tinted_weldhelh has been disabled!</B>", confidential = TRUE)
log_admin("[key_name(usr)] toggled tinted_weldhelh.")
message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Tinted Welding Helmets", "[GLOB.tinted_weldhelh ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/dynamic_mode_options(mob/user)
var/dat = {"
<center><B><h2>Dynamic Mode Options</h2></B></center><hr>
@@ -18,18 +18,18 @@
var/list/organs = user.getorganszone(BODY_ZONE_HEAD, TRUE)
explosion(user, light_impact_range = 2, adminlog = TRUE, explosion_cause = src)
for(var/mob/living/carbon/human/blinded_humans in range(2, user))
var/obj/item/organ/internal/eyes/eyes = blinded_humans.getorganslot(ORGAN_SLOT_EYES)
if(!eyes || blinded_humans.is_blind())
for(var/mob/living/carbon/human/blinded_human in range(2, user))
var/obj/item/organ/internal/eyes/eyes = blinded_human.getorganslot(ORGAN_SLOT_EYES)
if(!eyes || blinded_human.is_blind())
continue
to_chat(blinded_humans, span_userdanger("You are blinded by a shower of blood!"))
blinded_humans.Stun(20)
blinded_humans.set_eye_blur_if_lower(40 SECONDS)
blinded_humans.adjust_confusion(3 SECONDS)
to_chat(blinded_human, span_userdanger("You are blinded by a shower of blood!"))
blinded_human.Stun(2 SECONDS)
blinded_human.set_eye_blur_if_lower(40 SECONDS)
blinded_human.adjust_confusion(3 SECONDS)
for(var/mob/living/silicon/blinded_silicons in range(2,user))
to_chat(blinded_silicons, span_userdanger("Your sensors are disabled by a shower of blood!"))
blinded_silicons.Paralyze(60)
for(var/mob/living/silicon/blinded_silicon in range(2,user))
to_chat(blinded_silicon, span_userdanger("Your sensors are disabled by a shower of blood!"))
blinded_silicon.Paralyze(6 SECONDS)
var/turf/user_turf = get_turf(user)
user.transfer_observers_to(user_turf) // user is about to be deleted, store orbiters on the turf
@@ -206,10 +206,15 @@
dna_cost = 1
/datum/action/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target)
var/obj/item/organ/internal/eyes/eyes = target.getorganslot(ORGAN_SLOT_EYES)
if(!eyes)
to_chat(user, span_notice("You prepare to sting [target], but one of the voices in your hivemind points out they have no eyes."))
return FALSE
log_combat(user, target, "stung", "blind sting")
to_chat(target, span_danger("Your eyes burn horrifically!"))
target.become_nearsighted(EYE_DAMAGE)
target.adjust_blindness(20)
eyes.applyOrganDamage(eyes.maxHealth * 0.8)
target.adjust_temp_blindness(40 SECONDS)
target.set_eye_blur_if_lower(80 SECONDS)
return TRUE
+1 -1
View File
@@ -452,7 +452,7 @@ Striking a noncultist, however, will tear their flesh."}
user.dropItemToGround(src, TRUE)
user.set_dizzy_if_lower(1 MINUTES)
user.Paralyze(100)
user.adjust_blindness(30)
user.adjust_temp_blindness(60 SECONDS)
/obj/item/reagent_containers/cup/beaker/unholywater
name = "flask of unholy water"
@@ -53,9 +53,7 @@
REMOVE_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT)
for(var/mob/living/carbon/human/human_in_range in view(local_user))
if(IS_HERETIC_OR_MONSTER(human_in_range))
continue
if(human_in_range.is_blind())
if(IS_HERETIC_OR_MONSTER(human_in_range) || human_in_range.is_blind())
continue
human_in_range.mob_mood.direct_sanity_drain(rand(-2, -20) * delta_time)
@@ -85,15 +85,11 @@
/datum/status_effect/cloudstruck/on_apply()
owner.add_overlay(mob_overlay)
owner.become_blind(STATUS_EFFECT_TRAIT)
owner.update_blindness() // become_blind is supposed to call this but it doesn't work for some reason because blindness is a fuck
owner.become_blind(id)
return TRUE
/datum/status_effect/cloudstruck/on_remove()
if(QDELETED(owner))
return
owner.cure_blind(STATUS_EFFECT_TRAIT)
owner.update_blindness()
owner.cure_blind(id)
owner.cut_overlay(mob_overlay)
/datum/status_effect/corrosion_curse
@@ -244,6 +244,6 @@
carbon_victim.adjust_confusion(5 SECONDS)
carbon_victim.set_jitter_if_lower(20 SECONDS)
carbon_victim.set_dizzy_if_lower(40 SECONDS)
carbon_victim.adjust_blindness(2)
carbon_victim.adjust_temp_blindness(4 SECONDS)
carbon_victim.add_mood_event("gates_of_mansus", /datum/mood_event/gates_of_mansus)
playsound(src, 'sound/magic/blind.ogg', 75, TRUE)
@@ -201,7 +201,7 @@
if(!do_after(user, 5 SECONDS, target = victim, extra_checks = CALLBACK(src, PROC_REF(eyeballs_exist), eyeballies, head, victim)))
return
if(!HAS_TRAIT(victim, TRAIT_BLIND))
if(!victim.is_blind())
to_chat(victim, span_userdanger("You suddenly go blind!"))
if(prob(1))
to_chat(victim, span_notice("At least you got a new pirate-y look out of it..."))
+2 -2
View File
@@ -399,7 +399,7 @@
M.adjust_confusion_up_to(10 SECONDS, 20 SECONDS)
M.adjust_dizzy_up_to(20 SECONDS, 40 SECONDS)
M.adjust_drowsiness_up_to(20 SECONDS, 40 SECONDS)
M.apply_status_effect(/datum/status_effect/pacify, 100)
M.adjust_pacifism(10 SECONDS)
else
M.apply_status_effect(/datum/status_effect/trance, 200, TRUE)
@@ -413,7 +413,7 @@
M.adjust_confusion_up_to(4 SECONDS, 20 SECONDS)
M.adjust_dizzy_up_to(8 SECONDS, 40 SECONDS)
M.adjust_drowsiness_up_to(8 SECONDS, 40 SECONDS)
M.apply_status_effect(/datum/status_effect/pacify, 40)
M.adjust_pacifism(4 SECONDS)
#undef CONFUSION_STACK_MAX_MULTIPLIER
#undef DEVIATION_NONE
+5 -16
View File
@@ -20,8 +20,6 @@
var/lighting_alpha
/// The current hud icons
var/list/icon/current = list()
/// Does wearing these glasses correct some of our vision defects?
var/vision_correction = FALSE
/// Colors your vision when worn
var/glass_colour_type
/// Whether or not vision coloring is forcing
@@ -63,7 +61,7 @@
if(H.glasses == src)
to_chat(H, span_danger("[src] overloads and blinds you!"))
H.flash_act(visual = 1)
H.adjust_blindness(3)
H.adjust_temp_blindness(6 SECONDS)
H.set_eye_blur_if_lower(10 SECONDS)
eyes.applyOrganDamage(5)
@@ -243,7 +241,7 @@
desc = "Made by Nerd. Co."
icon_state = "glasses"
inhand_icon_state = "glasses"
vision_correction = TRUE //corrects nearsightedness
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/regular/Initialize(mapload)
. = ..()
@@ -269,7 +267,7 @@
/obj/item/clothing/glasses/regular/atom_destruction(damage_flag)
. = ..()
vision_correction = FALSE
clothing_traits -= TRAIT_NEARSIGHTED_CORRECTED
/obj/item/clothing/glasses/regular/welder_act(mob/living/user, obj/item/I)
. = ..()
@@ -285,7 +283,7 @@
/obj/item/clothing/glasses/regular/repair()
. = ..()
vision_correction = TRUE
clothing_traits |= TRAIT_NEARSIGHTED_CORRECTED
/obj/item/clothing/glasses/regular/thin
name = "thin prescription glasses"
@@ -397,19 +395,10 @@
icon_state = "blindfold"
inhand_icon_state = "blindfold"
flash_protect = FLASH_PROTECTION_WELDER
tint = 3
tint = INFINITY // You WILL Be blind, no matter what
darkness_view = 1
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/glasses/blindfold/equipped(mob/living/carbon/human/user, slot)
. = ..()
if(slot & ITEM_SLOT_EYES)
user.become_blind(BLINDFOLD_TRAIT)
/obj/item/clothing/glasses/blindfold/dropped(mob/living/carbon/human/user)
..()
user.cure_blind(BLINDFOLD_TRAIT)
/obj/item/clothing/glasses/trickblindfold
name = "blindfold"
desc = "A see-through blindfold perfect for cheating at games like pin the stun baton on the clown."
+1 -1
View File
@@ -68,7 +68,7 @@
/obj/item/clothing/mask/muzzle/tape/attack(mob/living/carbon/victim, mob/living/carbon/attacker, params)
if(attacker.combat_mode)
return ..()
if(victim.is_mouth_covered(head_only = TRUE))
if(victim.is_mouth_covered(ITEM_SLOT_HEAD))
to_chat(attacker, span_notice("[victim]'s mouth is covered."))
return
if(!mob_can_equip(victim, ITEM_SLOT_MASK))
@@ -105,6 +105,7 @@
if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer)
transfer_identity(C)
C.update_body_parts()
C.clear_mood_event("brain_damage")
/obj/item/organ/internal/brain/proc/transfer_identity(mob/living/L)
name = "[L.name]'s [initial(name)]"
@@ -477,6 +478,15 @@
amount_cured++
return amount_cured
/obj/item/organ/internal/brain/applyOrganDamage(damage_amount, maximum, required_organtype)
. = ..()
if(!owner)
return
if(damage >= 60)
owner.add_mood_event("brain_damage", /datum/mood_event/brain_damage)
else
owner.clear_mood_event("brain_damage")
/// This proc lets the mob's brain decide what bodypart to attack with in an unarmed strike.
/obj/item/organ/internal/brain/proc/get_attacking_limb(mob/living/carbon/human/target)
var/obj/item/bodypart/arm/active_hand = owner.get_active_hand()
-6
View File
@@ -30,9 +30,3 @@
emp_damage = 0
else
emp_damage = max(emp_damage - (0.5 * delta_time), 0)
/mob/living/brain/handle_traits(delta_time, times_fired)
return
@@ -1,11 +0,0 @@
//Here are the procs used to modify status effects of a mob.
//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness
// eye damage, eye_blind, TRAIT_BLIND trait, and TRAIT_NEARSIGHT trait.
/////////////////////////////////// EYE_BLIND ////////////////////////////////////
/mob/living/brain/adjust_blindness()
return
/mob/living/brain/set_blindness()
return
@@ -12,8 +12,6 @@
type_of_meat = /obj/item/food/meat/slab/xeno
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
var/move_delay_add = 0 // movement delay to add
status_flags = CANUNCONSCIOUS|CANPUSH
heat_protection = 0.5 // minor heat insulation
@@ -44,9 +44,3 @@
/mob/living/carbon/alien/adult/Life(delta_time, times_fired)
. = ..()
handle_organs(delta_time, times_fired)
/mob/living/carbon/alien/handle_traits(delta_time, times_fired)
. = ..()
//natural reduction of movement delay due to stun.
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - (0.5 * rand(1, 2) * delta_time))
@@ -158,7 +158,7 @@
span_userdanger("[src] leaps at your face!"))
// probiscis-blocker handling
if(target.is_mouth_covered(head_only = TRUE))
if(target.is_mouth_covered(ITEM_SLOT_HEAD))
target.visible_message(span_danger("[src] smashes against [target]'s [target.head]!"), \
span_userdanger("[src] smashes against your [target.head]!"))
Die()
@@ -263,7 +263,7 @@
var/mob/living/carbon/C = M
if(ishuman(C) && !(C.dna.species.no_equip_flags & ITEM_SLOT_MASK))
var/mob/living/carbon/human/H = C
if(H.is_mouth_covered(head_only = 1))
if(H.is_mouth_covered(ITEM_SLOT_HEAD))
return FALSE
return TRUE
return FALSE
@@ -1,20 +0,0 @@
//Here are the procs used to modify status effects of a mob.
//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness, ear damage,
// eye damage, eye_blind, TRAIT_BLIND trait, and TRAIT_NEARSIGHT trait.
/////////////////////////////////// STUN ////////////////////////////////////
/mob/living/carbon/alien/Stun(amount, ignore_canstun = FALSE)
. = ..()
if(!.)
move_delay_add = min(move_delay_add + round(amount / 2), 10) //a maximum delay of 10
/mob/living/carbon/alien/SetStun(amount, ignore_canstun = FALSE)
. = ..()
if(!.)
move_delay_add = min(move_delay_add + round(amount / 2), 10)
/mob/living/carbon/alien/AdjustStun(amount, ignore_canstun = FALSE)
. = ..()
if(!.)
move_delay_add = clamp(move_delay_add + round(amount/2), 0, 10)
+31 -32
View File
@@ -570,15 +570,14 @@
var/new_sight = initial(sight)
lighting_alpha = initial(lighting_alpha)
var/obj/item/organ/internal/eyes/E = getorganslot(ORGAN_SLOT_EYES)
if(!E)
update_tint()
else
set_invis_see(E.see_invisible)
set_see_in_dark(E.see_in_dark)
new_sight |= E.sight_flags
if(!isnull(E.lighting_alpha))
lighting_alpha = E.lighting_alpha
var/obj/item/organ/internal/eyes/eyes = getorganslot(ORGAN_SLOT_EYES)
if(eyes)
set_invis_see(eyes.see_invisible)
set_see_in_dark(eyes.see_in_dark)
new_sight |= eyes.sight_flags
if(!isnull(eyes.lighting_alpha))
lighting_alpha = eyes.lighting_alpha
if(client.eye && client.eye != src)
var/atom/A = client.eye
@@ -621,34 +620,34 @@
set_sight(new_sight)
return ..()
//to recalculate and update the mob's total tint from tinted equipment it's wearing.
/**
* Calculates how visually impaired the mob is by their equipment and other factors
*
* This is where clothing adds its various vision limiting effects, such as welding helmets
*/
/mob/living/carbon/proc/update_tint()
if(!GLOB.tinted_weldhelh)
return
tinttotal = get_total_tint()
if(tinttotal >= TINT_BLIND)
var/tint = 0
if(isclothing(head))
tint += head.tint
if(isclothing(wear_mask))
tint += wear_mask.tint
if(isclothing(glasses))
tint += glasses.tint
var/obj/item/organ/internal/eyes/eyes = getorganslot(ORGAN_SLOT_EYES)
if(eyes)
tint += eyes.tint
if(tint >= TINT_BLIND)
become_blind(EYES_COVERED)
else if(tinttotal >= TINT_DARKENED)
else if(tint >= TINT_DARKENED)
cure_blind(EYES_COVERED)
overlay_fullscreen("tint", /atom/movable/screen/fullscreen/impaired, 2)
else
cure_blind(EYES_COVERED)
clear_fullscreen("tint", 0)
/mob/living/carbon/proc/get_total_tint()
. = 0
if(isclothing(head))
. += head.tint
if(isclothing(wear_mask))
. += wear_mask.tint
var/obj/item/organ/internal/eyes/E = getorganslot(ORGAN_SLOT_EYES)
if(E)
. += E.tint
else
. += INFINITY
clear_fullscreen("tint", 0 SECONDS)
//this handles hud updates
/mob/living/carbon/update_damage_hud()
@@ -1205,7 +1204,7 @@
var/obscured = check_obscured_slots()
// If the eyes are covered by anything but glasses, that thing will be covering any potential glasses as well.
if(glasses && is_eyes_covered(FALSE, TRUE, TRUE) && glasses.wash(clean_types))
if(glasses && is_eyes_covered(ITEM_SLOT_MASK|ITEM_SLOT_HEAD) && glasses.wash(clean_types))
update_worn_glasses()
. = TRUE
@@ -4,13 +4,13 @@
/mob/living/carbon/get_eye_protection()
. = ..()
if(HAS_TRAIT_NOT_FROM(src, TRAIT_BLIND, list(UNCONSCIOUS_TRAIT, HYPNOCHAIR_TRAIT)))
if(is_blind() && !is_blind_from(list(UNCONSCIOUS_TRAIT, HYPNOCHAIR_TRAIT)))
return INFINITY //For all my homies that can not see in the world
var/obj/item/organ/internal/eyes/E = getorganslot(ORGAN_SLOT_EYES)
if(!E)
return INFINITY //Can't get flashed without eyes
var/obj/item/organ/internal/eyes/eyes = getorganslot(ORGAN_SLOT_EYES)
if(eyes)
. += eyes.flash_protect
else
. += E.flash_protect
return INFINITY //Can't get flashed without eyes
if(isclothing(head)) //Adds head protection
. += head.flash_protect
if(isclothing(glasses)) //Glasses
@@ -28,24 +28,32 @@
else
. += E.bang_protect
/mob/living/carbon/is_mouth_covered(head_only = FALSE, mask_only = FALSE)
if( (!mask_only && head && (head.flags_cover & HEADCOVERSMOUTH)) || (!head_only && wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH)) )
return TRUE
/mob/living/carbon/is_eyes_covered(check_glasses = TRUE, check_head = TRUE, check_mask = TRUE)
if(check_head && head && (head.flags_cover & HEADCOVERSEYES))
/mob/living/carbon/is_mouth_covered(check_flags = ALL)
if((check_flags & ITEM_SLOT_HEAD) && head && (head.flags_cover & HEADCOVERSMOUTH))
return head
if(check_mask && wear_mask && (wear_mask.flags_cover & MASKCOVERSEYES))
if((check_flags & ITEM_SLOT_MASK) && wear_mask && (wear_mask.flags_cover & HEADCOVERSMOUTH))
return wear_mask
if(check_glasses && glasses && (glasses.flags_cover & GLASSESCOVERSEYES))
return null
/mob/living/carbon/is_eyes_covered(check_flags = ALL)
if((check_flags & ITEM_SLOT_HEAD) && head && (head.flags_cover & HEADCOVERSEYES))
return head
if((check_flags & ITEM_SLOT_MASK) && wear_mask && (wear_mask.flags_cover & MASKCOVERSEYES))
return wear_mask
if((check_flags & ITEM_SLOT_EYES) && glasses && (glasses.flags_cover & GLASSESCOVERSEYES))
return glasses
/mob/living/carbon/is_pepper_proof(check_head = TRUE, check_mask = TRUE)
if(check_head &&(head?.flags_cover & PEPPERPROOF))
return null
/mob/living/carbon/is_pepper_proof(check_flags = ALL)
if((check_flags & ITEM_SLOT_HEAD) && head && (head.flags_cover & PEPPERPROOF))
return head
if(check_mask &&(wear_mask?.flags_cover & PEPPERPROOF))
if((check_flags & ITEM_SLOT_MASK) && wear_mask && (wear_mask.flags_cover & PEPPERPROOF))
return wear_mask
return null
/mob/living/carbon/check_projectile_dismemberment(obj/projectile/P, def_zone)
var/obj/item/bodypart/affecting = get_bodypart(def_zone)
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
@@ -630,40 +638,39 @@
if(visual)
return
if (damage == 1)
to_chat(src, span_warning("Your eyes sting a little."))
if(prob(40))
eyes.applyOrganDamage(1)
switch(damage)
if(1)
to_chat(src, span_warning("Your eyes sting a little."))
if(prob(40))
eyes.applyOrganDamage(1)
else if (damage == 2)
to_chat(src, span_warning("Your eyes burn."))
eyes.applyOrganDamage(rand(2, 4))
if(2)
to_chat(src, span_warning("Your eyes burn."))
eyes.applyOrganDamage(rand(2, 4))
else if( damage >= 3)
to_chat(src, span_warning("Your eyes itch and burn severely!"))
eyes.applyOrganDamage(rand(12, 16))
if(3 to INFINITY)
to_chat(src, span_warning("Your eyes itch and burn severely!"))
eyes.applyOrganDamage(rand(12, 16))
if(eyes.damage > 10)
adjust_blindness(damage)
adjust_temp_blindness(damage * 2 SECONDS)
set_eye_blur_if_lower(damage * rand(6 SECONDS, 12 SECONDS))
if(eyes.damage > 20)
if(prob(eyes.damage - 20))
if(!HAS_TRAIT(src, TRAIT_NEARSIGHT))
to_chat(src, span_warning("Your eyes start to burn badly!"))
become_nearsighted(EYE_DAMAGE)
if(eyes.damage > eyes.low_threshold)
if(!is_nearsighted_from(EYE_DAMAGE) && prob(eyes.damage - eyes.low_threshold))
to_chat(src, span_warning("Your eyes start to burn badly!"))
eyes.applyOrganDamage(eyes.low_threshold)
else if(prob(eyes.damage - 25))
if(!is_blind())
to_chat(src, span_warning("You can't see anything!"))
else if(!is_blind() && prob(eyes.damage - eyes.high_threshold))
to_chat(src, span_warning("You can't see anything!"))
eyes.applyOrganDamage(eyes.maxHealth)
else
to_chat(src, span_warning("Your eyes are really starting to hurt. This can't be good for you!"))
return 1
else if(damage == 0) // just enough protection
if(prob(20))
to_chat(src, span_notice("Something bright flashes in the corner of your vision!"))
return TRUE
else if(damage == 0 && prob(20)) // just enough protection
to_chat(src, span_notice("Something bright flashes in the corner of your vision!"))
/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
@@ -67,9 +67,6 @@
var/rotate_on_lying = 1
/// Total level of visualy impairing items
var/tinttotal = 0
/// Gets filled up in [/datum/species/proc/replace_body].
/// Will either contain a list of typepaths if nothing has been created yet,
/// or a list of the body part objects.
@@ -352,7 +352,7 @@
if(mob_mood.sanity <= SANITY_DISTURBED)
msg += "[t_He] seem[p_s()] distressed.\n"
living_user.add_mood_event("empath", /datum/mood_event/sad_empath, src)
if (is_blind())
if(is_blind())
msg += "[t_He] appear[p_s()] to be staring off into space.\n"
if (HAS_TRAIT(src, TRAIT_DEAF))
msg += "[t_He] appear[p_s()] to not be responding to noises.\n"
+4 -12
View File
@@ -6,6 +6,9 @@
setup_mood()
// All start without eyes, and get them via set species
become_blind(NO_EYES)
create_dna()
dna.species.create_fresh_body(src)
setup_human_dna()
@@ -647,7 +650,7 @@
if(!is_mouth_covered() && clean_lips())
. = TRUE
if(glasses && is_eyes_covered(FALSE, TRUE, TRUE) && glasses.wash(clean_types))
if(glasses && is_eyes_covered(ITEM_SLOT_MASK|ITEM_SLOT_HEAD) && glasses.wash(clean_types))
update_worn_glasses()
. = TRUE
@@ -738,11 +741,6 @@
if(general_record)
general_record.fields["name"] = newname
/mob/living/carbon/human/get_total_tint()
. = ..()
if(glasses)
. += glasses.tint
/mob/living/carbon/human/update_health_hud()
if(!client || !hud_used)
return
@@ -799,12 +797,6 @@
return ..()
/mob/living/carbon/human/is_nearsighted()
var/obj/item/clothing/glasses/eyewear = glasses
if(istype(eyewear) && eyewear.vision_correction)
return FALSE
return ..()
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
if(blood && HAS_TRAIT(src, TRAIT_NOBLOOD) && !HAS_TRAIT(src, TRAIT_TOXINLOVER))
if(message)
@@ -136,8 +136,6 @@
update_glasses_color(G, 1)
if(G.tint)
update_tint()
if(G.vision_correction)
clear_fullscreen("nearsighted")
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
update_sight()
update_worn_glasses()
@@ -263,9 +261,6 @@
update_glasses_color(G, 0)
if(G.tint)
update_tint()
if(G.vision_correction)
if(HAS_TRAIT(src, TRAIT_NEARSIGHT))
overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/impaired, 1)
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
update_sight()
if(!QDELETED(src))
@@ -70,14 +70,6 @@
return (occupied_space.contents_pressure_protection * ONE_ATMOSPHERE + (1 - occupied_space.contents_pressure_protection) * pressure)
return pressure
/mob/living/carbon/human/handle_traits(delta_time, times_fired)
if (getOrganLoss(ORGAN_SLOT_BRAIN) >= 60)
add_mood_event("brain_damage", /datum/mood_event/brain_damage)
else
clear_mood_event("brain_damage")
return ..()
/mob/living/carbon/human/breathe()
if(!HAS_TRAIT(src, TRAIT_NOBREATH))
return ..()
@@ -921,8 +921,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(ITEM_SLOT_EYES)
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
var/obj/item/organ/internal/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
if(E?.no_glasses)
var/obj/item/organ/internal/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
if(eyes?.no_glasses)
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_HEAD)
@@ -1149,7 +1149,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
var/atk_effect = attacking_bodypart.unarmed_attack_effect
if(atk_effect == ATTACK_EFFECT_BITE)
if(user.is_mouth_covered(mask_only = TRUE))
if(user.is_mouth_covered(ITEM_SLOT_MASK))
to_chat(user, span_warning("You can't [atk_verb] with your mouth covered!"))
return FALSE
user.do_attack_animation(target, atk_effect)
@@ -1,6 +1,5 @@
//Here are the procs used to modify status effects of a mob.
//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness, ear damage,
//eye_blind, TRAIT_BLIND trait, TRAIT_NEARSIGHT trait, and TRAIT_HUSK trait.
//The effects include: stun, knockdown, unconscious, sleeping, resting
/mob/living/carbon/IsParalyzed(include_stamcrit = TRUE)
-11
View File
@@ -67,9 +67,6 @@
handle_gravity(delta_time, times_fired)
if(stat != DEAD)
handle_traits(delta_time, times_fired) // eye, ear, brain damages
if(machine)
machine.check_eye(src)
@@ -136,14 +133,6 @@
/mob/living/proc/has_reagent(reagent, amount = -1, needs_metabolizing = FALSE)
return reagents.has_reagent(reagent, amount, needs_metabolizing)
/mob/living/proc/handle_traits(delta_time, times_fired)
//Eyes
if(eye_blind) //blindness, heals slowly over time
if(HAS_TRAIT_FROM(src, TRAIT_BLIND, EYES_COVERED)) //covering your eyes heals blurry eyes faster
adjust_blindness(-1.5 * delta_time)
else if(!stat && !(HAS_TRAIT(src, TRAIT_BLIND)))
adjust_blindness(-0.5 * delta_time)
/mob/living/proc/update_damage_hud()
return
-3
View File
@@ -896,10 +896,7 @@
// These should be tracked by status effects
losebreath = 0
set_blindness(0)
set_disgust(0)
cure_nearsighted()
cure_blind()
cure_husk()
if(heal_flags & HEAL_TEMP)
+42 -7
View File
@@ -46,13 +46,48 @@
return 1
return 0
/mob/living/proc/is_mouth_covered(head_only = 0, mask_only = 0)
return FALSE
/**
* Checks if our mob has their mouth covered.
*
* Note that we only care about [ITEM_SLOT_HEAD] and [ITEM_SLOT_MASK].
* (so if you check all slots, it'll return head, then mask)
*That is also the priority order
* Arguments
* * check_flags: What item slots should we check?
*
* Retuns a truthy value (a ref to what is covering mouth), or a falsy value (null)
*/
/mob/living/proc/is_mouth_covered(check_flags = ALL)
return null
/**
* Checks if our mob has their eyes covered.
*
* Note that we only care about [ITEM_SLOT_HEAD], [ITEM_SLOT_MASK], and [ITEM_SLOT_GLASSES].
* That is also the priority order (so if you check all slots, it'll return head, then mask, then glasses)
*
* Arguments
* * check_flags: What item slots should we check?
*
* Retuns a truthy value (a ref to what is covering eyes), or a falsy value (null)
*/
/mob/living/proc/is_eyes_covered(check_flags = ALL)
return null
/**
* Checks if our mob is protected from pepper spray.
*
* Note that we only care about [ITEM_SLOT_HEAD] and [ITEM_SLOT_MASK].
* That is also the priority order (so if you check all slots, it'll return head, then mask)
*
* Arguments
* * check_flags: What item slots should we check?
*
* Retuns a truthy value (a ref to what is protecting us), or a falsy value (null)
*/
/mob/living/proc/is_pepper_proof(check_flags = ALL)
return null
/mob/living/proc/is_eyes_covered(check_glasses = 1, check_head = 1, check_mask = 1)
return FALSE
/mob/living/proc/is_pepper_proof(check_head = TRUE, check_mask = TRUE)
return FALSE
/mob/living/proc/on_hit(obj/projectile/P)
return BULLET_ACT_HIT
@@ -289,7 +324,7 @@
to_chat(user, span_warning("You don't want to hurt anyone!"))
return FALSE
if(user.is_muzzled() || user.is_mouth_covered(FALSE, TRUE))
if(user.is_muzzled() || user.is_mouth_covered(ITEM_SLOT_MASK))
to_chat(user, span_warning("You can't bite with your mouth covered!"))
return FALSE
user.do_attack_animation(src, ATTACK_EFFECT_BITE)
+1 -1
View File
@@ -45,7 +45,7 @@
. = TRUE
// Handling nearsightnedness
if(. && is_nearsighted())
if(. && is_nearsighted_currently())
if((rel_x >= NEARSIGHTNESS_FOV_BLINDNESS || rel_x <= -NEARSIGHTNESS_FOV_BLINDNESS) || (rel_y >= NEARSIGHTNESS_FOV_BLINDNESS || rel_y <= -NEARSIGHTNESS_FOV_BLINDNESS))
return FALSE
+2 -2
View File
@@ -291,13 +291,13 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
deaf_type = MSG_AUDIBLE
// Create map text prior to modifying message for goonchat, sign lang edition
if (client?.prefs.read_preference(/datum/preference/toggle/enable_runechat) && !(stat == UNCONSCIOUS || stat == HARD_CRIT || is_blind(src)) && (client.prefs.read_preference(/datum/preference/toggle/enable_runechat_non_mobs) || ismob(speaker)))
if (client?.prefs.read_preference(/datum/preference/toggle/enable_runechat) && !(stat == UNCONSCIOUS || stat == HARD_CRIT || is_blind()) && (client.prefs.read_preference(/datum/preference/toggle/enable_runechat_non_mobs) || ismob(speaker)))
if (message_mods[MODE_CUSTOM_SAY_ERASE_INPUT])
create_chat_message(speaker, null, message_mods[MODE_CUSTOM_SAY_EMOTE], spans, EMOTE_MESSAGE)
else
create_chat_message(speaker, message_language, raw_message, spans)
if(is_blind(src))
if(is_blind())
return FALSE
message = deaf_message
+2 -4
View File
@@ -5,8 +5,6 @@
update_gravity(has_gravity())
handle_traits(delta_time, times_fired)
if(malfhack?.aidisabled)
deltimer(malfhacking)
// This proc handles cleanup of screen notifications and
@@ -155,14 +153,14 @@
else
to_chat(src, span_notice("Alert cancelled. Power has been restored without our assistance."))
setAiRestorePowerRoutine(POWER_RESTORATION_OFF)
set_blindness(0)
remove_status_effect(/datum/status_effect/temporary_blindness)
apc_override = null
update_sight()
/mob/living/silicon/ai/proc/ai_lose_power()
disconnect_shell()
setAiRestorePowerRoutine(POWER_RESTORATION_START)
adjust_blindness(1)
adjust_temp_blindness(2 SECONDS)
update_sight()
to_chat(src, span_alert("You've lost power!"))
addtimer(CALLBACK(src, PROC_REF(start_RestorePowerRoutine)), 20)
@@ -81,8 +81,7 @@
if(!M.is_blind())
return M
for(var/obj/vehicle/sealed/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you
for(var/O in M.occupants)
var/mob/mechamob = O
for(var/mob/mechamob as anything in M.occupants)
if(mechamob.client && !mechamob.is_blind())
return mechamob
return null
@@ -195,4 +195,4 @@
return things
/datum/action/cooldown/spell/aoe/blindness/cast_on_thing_in_aoe(mob/living/victim, atom/caster)
victim.adjust_blindness(4)
victim.adjust_temp_blindness(8 SECONDS)
@@ -13,9 +13,12 @@
if(!.)
return
if(buckled)
// We get some passive bruteloss healing if we're not dead
if(stat != DEAD && DT_PROB(16, delta_time))
adjustBruteLoss(-0.5 * delta_time)
if(ismob(buckled))
handle_feeding(delta_time, times_fired)
if(stat) // Slimes in stasis don't lose nutrition, don't change mood and don't respond to speech
if(stat != CONSCIOUS) // Slimes in stasis don't lose nutrition, don't change mood and don't respond to speech
return
handle_nutrition(delta_time, times_fired)
if(QDELETED(src)) // Stop if the slime split during handle_nutrition()
@@ -164,15 +167,7 @@
updatehealth()
/mob/living/simple_animal/slime/handle_traits(delta_time, times_fired)
. = ..()
if(!stat && DT_PROB(16, delta_time))
adjustBruteLoss(-0.5 * delta_time)
/mob/living/simple_animal/slime/proc/handle_feeding(delta_time, times_fired)
if(!ismob(buckled))
return
var/mob/M = buckled
if(stat)
@@ -1,9 +0,0 @@
/mob/living/simple_animal/adjust_blindness()
return
/mob/living/simple_animal/set_blindness()
return
/mob/living/simple_animal/become_blind()
return
+1 -28
View File
@@ -1,6 +1,5 @@
//Here are the procs used to modify status effects of a mob.
//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness,
// eye damage, eye_blind, TRAIT_BLIND trait, and TRAIT_NEARSIGHT trait.
//The effects include: stun, knockdown, unconscious, sleeping, resting
#define IS_STUN_IMMUNE(source, ignore_canstun) ((source.status_flags & GODMODE) || (!ignore_canstun && (!(source.status_flags & CANKNOCKDOWN) || HAS_TRAIT(source, TRAIT_STUNIMMUNE))))
@@ -518,32 +517,6 @@
return TRUE
return FALSE
/* TRAIT PROCS */
/mob/living/proc/cure_blind(source)
if(source)
REMOVE_TRAIT(src, TRAIT_BLIND, source)
else
REMOVE_TRAIT_NOT_FROM(src, TRAIT_BLIND, list(QUIRK_TRAIT, EYES_COVERED, BLINDFOLD_TRAIT))
if(!HAS_TRAIT(src, TRAIT_BLIND))
update_blindness()
/mob/living/proc/become_blind(source)
if(!HAS_TRAIT(src, TRAIT_BLIND)) // not blind already, add trait then overlay
ADD_TRAIT(src, TRAIT_BLIND, source)
update_blindness()
else
ADD_TRAIT(src, TRAIT_BLIND, source)
/mob/living/proc/cure_nearsighted(source)
REMOVE_TRAIT(src, TRAIT_NEARSIGHT, source)
if(!HAS_TRAIT(src, TRAIT_NEARSIGHT))
clear_fullscreen("nearsighted")
/mob/living/proc/become_nearsighted(source)
if(!HAS_TRAIT(src, TRAIT_NEARSIGHT))
overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/impaired, 1)
ADD_TRAIT(src, TRAIT_NEARSIGHT, source)
/mob/living/proc/cure_husk(source)
REMOVE_TRAIT(src, TRAIT_HUSK, source)
if(!HAS_TRAIT(src, TRAIT_HUSK))
+1 -8
View File
@@ -211,7 +211,7 @@
msg = copytext_char(msg, 1, MAX_MESSAGE_LEN)
if(type)
if(type & MSG_VISUAL && is_blind() )//Vision related
if(type & MSG_VISUAL && is_blind())//Vision related
if(!alt_msg)
return
else
@@ -1191,10 +1191,6 @@
/mob/proc/has_nightvision()
return see_in_dark >= NIGHTVISION_FOV_RANGE
/// Is this mob affected by nearsight
/mob/proc/is_nearsighted()
return HAS_TRAIT(src, TRAIT_NEARSIGHT)
/// This mob is abile to read books
/mob/proc/is_literate()
return HAS_TRAIT(src, TRAIT_LITERATE) && !HAS_TRAIT(src, TRAIT_ILLITERATE)
@@ -1402,9 +1398,6 @@
if(NAMEOF(src, stat))
set_stat(var_value)
. = TRUE
if(NAMEOF(src, eye_blind))
set_blindness(var_value)
. = TRUE
if(!isnull(.))
datum_flags |= DF_VAR_EDITED
-2
View File
@@ -83,8 +83,6 @@
*/
var/notransform = null //Carbon
/// Is the mob blind
var/eye_blind = 0 //Carbon
/// What is the mobs real name (name is overridden for disguises etc)
var/real_name = null
-5
View File
@@ -206,11 +206,6 @@
return " \[[real_name]\]"
return ""
///Checks if the mob is able to see or not. eye_blind is temporary blindness, the trait is if they're permanently blind.
/mob/proc/is_blind()
SHOULD_BE_PURE(TRUE)
return eye_blind ? TRUE : HAS_TRAIT(src, TRAIT_BLIND)
// moved out of admins.dm because things other than admin procs were calling this.
/// Returns TRUE if the game has started and we're either an AI with a 0th law, or we're someone with a special role/antag datum
/proc/is_special_character(mob/M)
-45
View File
@@ -1,49 +1,4 @@
//Here are the procs used to modify status effects of a mob.
/**
* Adjust a mobs blindness by an amount
*
* Will apply the blind alerts if needed
*/
/mob/proc/adjust_blindness(amount)
var/old_eye_blind = eye_blind
eye_blind = max(0, eye_blind + amount)
if(!old_eye_blind || !eye_blind && !HAS_TRAIT(src, TRAIT_BLIND))
update_blindness()
/**
* Force set the blindness of a mob to some level
*/
/mob/proc/set_blindness(amount)
var/old_eye_blind = eye_blind
eye_blind = max(amount, 0)
if(!old_eye_blind || !eye_blind && !HAS_TRAIT(src, TRAIT_BLIND))
update_blindness()
/// proc that adds and removes blindness overlays when necessary
/mob/proc/update_blindness()
switch(stat)
if(CONSCIOUS, SOFT_CRIT)
if(HAS_TRAIT(src, TRAIT_BLIND) || eye_blind)
throw_alert(ALERT_BLIND, /atom/movable/screen/alert/blind)
do_set_blindness(TRUE)
else
do_set_blindness(FALSE)
if(UNCONSCIOUS, HARD_CRIT)
do_set_blindness(TRUE)
if(DEAD)
do_set_blindness(FALSE)
///Proc that handles adding and removing the blindness overlays.
/mob/proc/do_set_blindness(now_blind)
if(now_blind)
overlay_fullscreen("blind", /atom/movable/screen/fullscreen/blind)
// You are blind why should you be able to make out details like color, only shapes near you
add_client_colour(/datum/client_colour/monochrome/blind)
else
clear_alert(ALERT_BLIND)
clear_fullscreen("blind")
remove_client_colour(/datum/client_colour/monochrome/blind)
///Adjust the disgust level of a mob
/mob/proc/adjust_disgust(amount)
@@ -88,17 +88,16 @@
/datum/reagent/consumable/carrotjuice/on_mob_life(mob/living/carbon/affected_mob, delta_time, times_fired)
affected_mob.adjust_eye_blur(-2 SECONDS * REM * delta_time)
affected_mob.adjust_blindness(-1 * REM * delta_time)
affected_mob.adjust_temp_blindness(-2 SECONDS * REM * delta_time)
switch(current_cycle)
if(1 to 20)
//nothing
if(21 to 110)
if(DT_PROB(100 * (1 - (sqrt(110 - current_cycle) / 10)), delta_time))
affected_mob.cure_nearsighted(list(EYE_DAMAGE))
affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2)
if(110 to INFINITY)
affected_mob.cure_nearsighted(list(EYE_DAMAGE))
..()
return
affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2)
return ..()
/datum/reagent/consumable/berryjuice
name = "Berry Juice"
@@ -383,16 +383,14 @@
var/mob/living/carbon/victim = exposed_mob
if(methods & (TOUCH|VAPOR))
var/pepper_proof = victim.is_pepper_proof()
//check for protection
//actually handle the pepperspray effects
if (!(pepper_proof)) // you need both eye and mouth protection
if (!victim.is_pepper_proof()) // you need both eye and mouth protection
if(prob(5))
victim.emote("scream")
victim.emote("cry")
victim.set_eye_blur_if_lower(10 SECONDS)
victim.adjust_blindness(3) // 6 seconds
victim.adjust_temp_blindness(6 SECONDS)
victim.set_confusion_if_lower(5 SECONDS)
victim.Knockdown(3 SECONDS)
victim.add_movespeed_modifier(/datum/movespeed_modifier/reagent/pepperspray)
@@ -498,7 +496,7 @@
if (!tear_proof)
to_chat(exposed_mob, span_warning("Your eyes sting!"))
victim.emote("cry")
victim.set_eye_blur_if_lower(6 SECONDS)
victim.adjust_eye_blur(6 SECONDS)
/datum/reagent/consumable/sprinkles
name = "Sprinkles"
@@ -28,13 +28,10 @@
ph = 7
liver_damage = 0
/datum/reagent/impurity/methanol/on_mob_life(mob/living/carbon/owner, delta_time)
var/obj/item/organ/internal/eyes/eyes = owner.getorganslot(ORGAN_SLOT_EYES)
if(!eyes)
return ..()
eyes.applyOrganDamage(0.5 * REM * delta_time, required_organtype = affected_organtype)
..()
/datum/reagent/impurity/methanol/on_mob_life(mob/living/carbon/affected_mob, delta_time, times_fired)
var/obj/item/organ/internal/eyes/eyes = affected_mob.getorganslot(ORGAN_SLOT_EYES)
eyes?.applyOrganDamage(0.5 * REM * delta_time, required_organtype = affected_organtype)
return ..()
//Chloral Hydrate - Impure Version
/datum/reagent/impurity/chloralax
@@ -667,26 +667,24 @@
restore_eyesight(prev_affected_mob, eyes)
/datum/reagent/medicine/oculine/on_mob_life(mob/living/carbon/affected_mob, delta_time, times_fired)
affected_mob.adjust_blindness(-2 * REM * delta_time * normalise_creation_purity())
affected_mob.adjust_eye_blur(-4 SECONDS * REM * delta_time * normalise_creation_purity())
var/normalized_purity = normalise_creation_purity()
affected_mob.adjust_temp_blindness(-4 SECONDS * REM * delta_time * normalized_purity)
affected_mob.adjust_eye_blur(-4 SECONDS * REM * delta_time * normalized_purity)
var/obj/item/organ/internal/eyes/eyes = affected_mob.getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return ..()
var/fix_prob = 10
if(creation_purity >= 1)
fix_prob = 100
eyes.applyOrganDamage(-2 * REM * delta_time * normalise_creation_purity(), required_organtype = affected_organtype)
if(HAS_TRAIT_FROM(affected_mob, TRAIT_BLIND, EYE_DAMAGE))
if(DT_PROB(fix_prob, delta_time))
to_chat(affected_mob, span_warning("Your vision slowly returns..."))
affected_mob.cure_blind(EYE_DAMAGE)
affected_mob.cure_nearsighted(EYE_DAMAGE)
affected_mob.set_eye_blur_if_lower(70 SECONDS)
else if(HAS_TRAIT_FROM(affected_mob, TRAIT_NEARSIGHT, EYE_DAMAGE))
to_chat(affected_mob, span_warning("The blackness in your peripheral vision fades."))
affected_mob.cure_nearsighted(EYE_DAMAGE)
affected_mob.set_eye_blur_if_lower(20 SECONDS)
..()
if(eyes)
// Healing eye damage will cure nearsightedness and blindness from ... eye damage
eyes.applyOrganDamage(-2 * REM * delta_time * normalise_creation_purity(), required_organtype = affected_organtype)
// If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity
if(eyes.damaged && DT_PROB(16 - min(normalized_purity * 6, 12), delta_time))
// While healing, gives some eye blur
if(affected_mob.is_blind_from(EYE_DAMAGE))
to_chat(affected_mob, span_warning("Your vision slowly returns..."))
affected_mob.adjust_eye_blur(20 SECONDS)
else if(affected_mob.is_nearsighted_from(EYE_DAMAGE))
to_chat(affected_mob, span_warning("The blackness in your peripheral vision begins to fade."))
affected_mob.adjust_eye_blur(5 SECONDS)
return ..()
/datum/reagent/medicine/oculine/on_mob_delete(mob/living/affected_mob)
var/obj/item/organ/internal/eyes/eyes = affected_mob.getorganslot(ORGAN_SLOT_EYES)
+2 -2
View File
@@ -165,9 +165,9 @@
return FALSE
var/mob/living/carbon/C = eater
var/covered = ""
if(C.is_mouth_covered(head_only = 1))
if(C.is_mouth_covered(ITEM_SLOT_HEAD))
covered = "headgear"
else if(C.is_mouth_covered(mask_only = 1))
else if(C.is_mouth_covered(ITEM_SLOT_MASK))
covered = "mask"
if(covered)
var/who = (isnull(user) || eater == user) ? "your" : "[eater.p_their()]"
+18 -2
View File
@@ -35,15 +35,31 @@
limb_id = BODYPART_ID_PSYKER
is_dimorphic = FALSE
should_draw_greyscale = FALSE
bodypart_traits = list(TRAIT_DISFIGURED, TRAIT_BALD, TRAIT_SHAVED, TRAIT_BLIND)
bodypart_traits = list(TRAIT_DISFIGURED, TRAIT_BALD, TRAIT_SHAVED)
/obj/item/bodypart/head/psyker/try_attach_limb(mob/living/carbon/new_head_owner, special, abort)
. = ..()
if(!. || !new_head_owner.dna?.species)
if(!.)
return
new_head_owner.become_blind(limb_id)
if(!new_head_owner.dna?.species)
return
new_head_owner.dna.species.species_traits |= NOEYESPRITES //MAKE VISUALS TIED TO BODYPARTS ARGHH
new_head_owner.update_body()
/obj/item/bodypart/head/psyker/drop_limb(special, dismembered)
owner.cure_blind(limb_id)
if(!owner.dna?.species)
return ..()
if(initial(owner.dna.species.species_traits) & NOEYESPRITES)
return ..()
owner.dna.species.species_traits &= ~NOEYESPRITES
owner.update_body()
return ..()
/// flavorful variant of psykerizing that deals damage and sends messages before calling psykerize()
/mob/living/carbon/human/proc/slow_psykerize()
if(stat == DEAD || !get_bodypart(BODY_ZONE_HEAD) || istype(get_bodypart(BODY_ZONE_HEAD), /obj/item/bodypart/head/psyker))
@@ -36,21 +36,8 @@
to_chat(cast_on, span_userdanger("A freezing darkness surrounds you..."))
cast_on.playsound_local(get_turf(cast_on), 'sound/hallucinations/i_see_you1.ogg', 50, 1)
owner.playsound_local(get_turf(owner), 'sound/effects/ghost2.ogg', 50, 1)
cast_on.become_blind(ABYSSAL_GAZE_BLIND)
addtimer(CALLBACK(src, PROC_REF(cure_blindness), cast_on), blind_duration)
cast_on.adjust_temp_blindness(blind_duration)
if(ishuman(cast_on))
var/mob/living/carbon/human/human_cast_on = cast_on
human_cast_on.adjust_coretemperature(-amount_to_cool)
cast_on.adjust_bodytemperature(-amount_to_cool)
/**
* cure_blidness: Cures Abyssal Gaze blindness from the target
*
* Arguments:
* * target The mob that is being cured of the blindness.
*/
/datum/action/cooldown/spell/pointed/abyssal_gaze/proc/cure_blindness(mob/living/carbon/cast_on)
if(QDELETED(cast_on) || !istype(cast_on))
return
cast_on.cure_blind(ABYSSAL_GAZE_BLIND)
@@ -16,11 +16,9 @@
active_msg = "You prepare to blind a target..."
/// The amount of blind to apply
var/eye_blind_amount = 10
var/eye_blind_duration = 20 SECONDS
/// The amount of blurriness to apply
var/eye_blur_duration = 40 SECONDS
/// The duration of the blind mutation placed on the person
var/blind_mutation_duration = 30 SECONDS
/datum/action/cooldown/spell/pointed/blind/is_valid_target(atom/cast_on)
. = ..()
@@ -40,12 +38,6 @@
return FALSE
to_chat(cast_on, span_warning("Your eyes cry out in pain!"))
cast_on.adjust_blindness(eye_blind_amount)
cast_on.adjust_temp_blindness(eye_blind_duration)
cast_on.set_eye_blur_if_lower(eye_blur_duration)
if(cast_on.dna && blind_mutation_duration > 0 SECONDS)
cast_on.dna.add_mutation(/datum/mutation/human/blind)
addtimer(CALLBACK(src, PROC_REF(fix_eyes), cast_on), blind_mutation_duration)
return TRUE
/datum/action/cooldown/spell/pointed/blind/proc/fix_eyes(mob/living/carbon/human/cast_on)
cast_on.dna?.remove_mutation(/datum/mutation/human/blind)
+2 -4
View File
@@ -48,11 +48,9 @@
span_notice("[user] completes the surgery on [target]'s eyes."),
)
display_pain(target, "Your vision blurs, but it seems like you can see a little better now!")
target.cure_blind(list(EYE_DAMAGE))
target.set_blindness(0)
target.cure_nearsighted(list(EYE_DAMAGE))
target.remove_status_effect(/datum/status_effect/temporary_blindness)
target.set_eye_blur_if_lower(70 SECONDS) //this will fix itself slowly.
target_eyes.setOrganDamage(0)
target_eyes.setOrganDamage(0) // heals nearsightedness and blindness from eye damage
return ..()
/datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+6 -8
View File
@@ -179,8 +179,13 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
return
damage = clamp(damage + damage_amount, 0, maximum)
var/mess = check_damage_thresholds(owner)
check_failing_thresholds()
prev_damage = damage
if(damage >= maxHealth)
organ_flags |= ORGAN_FAILING
else
organ_flags &= ~ORGAN_FAILING
if(mess && owner && owner.stat <= SOFT_CRIT)
to_chat(owner, mess)
@@ -213,13 +218,6 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
if(prev_damage == maxHealth)
return now_fixed
///Checks if an organ should/shouldn't be failing and gives the appropriate organ flag
/obj/item/organ/proc/check_failing_thresholds()
if(damage >= maxHealth)
organ_flags |= ORGAN_FAILING
if(damage < maxHealth)
organ_flags &= ~ORGAN_FAILING
//Looking for brains?
//Try code/modules/mob/living/carbon/brain/brain_item.dm
+92 -77
View File
@@ -20,79 +20,74 @@
high_threshold_cleared = "<span class='info'>Your vision functions passably once more.</span>"
low_threshold_cleared = "<span class='info'>Your vision is cleared of any ailment.</span>"
var/sight_flags = 0
/// Sight flags this eye pair imparts on its user.
var/sight_flags = NONE
/// changes how the eyes overlay is applied, makes it apply over the lighting layer
var/overlay_ignore_lighting = FALSE
/// How much a mob can see in the dark with these eyes
var/see_in_dark = 2
/// How much innate tint these eyes have
var/tint = 0
/// How much innare flash protection these eyes have, usually paired with tint
var/flash_protect = FLASH_PROTECTION_NONE
/// What level of invisibility these eyes can see
var/see_invisible = SEE_INVISIBLE_LIVING
/// How much alpha lighting has (basically, night vision)
var/lighting_alpha
var/eye_color_left = "" //set to a hex code to override a mob's left eye color
var/eye_color_right = "" //set to a hex code to override a mob's right eye color
var/eye_icon_state = "eyes"
var/old_eye_color_left = "fff"
var/old_eye_color_right = "fff"
var/flash_protect = FLASH_PROTECTION_NONE
var/see_invisible = SEE_INVISIBLE_LIVING
var/lighting_alpha
var/no_glasses
/// Glasses cannot be worn over these eyes. Currently unused
var/no_glasses = FALSE
/// indication that the eyes are undergoing some negative effect
var/damaged = FALSE
/// Native FOV that will be applied if a config is enabled
var/native_fov = FOV_180_DEGREES //SKYRAT EDIT CHANGE
/obj/item/organ/internal/eyes/Insert(mob/living/carbon/eye_owner, special = FALSE, drop_if_replaced = FALSE, initialising)
/obj/item/organ/internal/eyes/Insert(mob/living/carbon/eye_owner, special = FALSE, drop_if_replaced = FALSE)
. = ..()
if(ishuman(eye_owner))
var/mob/living/carbon/human/human_owner = eye_owner
// SKYRAT EDIT ADDITION
if(human_owner.emissive_eyes)
is_emissive = TRUE
// SKYRAT EDIT END
old_eye_color_left = human_owner.eye_color_left
old_eye_color_right = human_owner.eye_color_right
if(initial(eye_color_left))
human_owner.eye_color_left = eye_color_left
else
eye_color_left = human_owner.eye_color_left
if(initial(eye_color_right))
human_owner.eye_color_right = eye_color_right
else
eye_color_right = human_owner.eye_color_right
if(HAS_TRAIT(human_owner, TRAIT_NIGHT_VISION) && !lighting_alpha)
lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT
if(CONFIG_GET(flag/native_fov) && native_fov)
human_owner.add_fov_trait(type, native_fov)
eye_owner.update_tint()
owner.update_sight()
if(eye_owner.has_dna() && ishuman(eye_owner))
eye_owner.dna.species.handle_body(eye_owner) //updates eye icon
owner.cure_blind(NO_EYES)
apply_damaged_eye_effects()
refresh()
/// Refreshes the visuals of the eyes
/// If call_update is TRUE, we also will call udpate_body
/obj/item/organ/internal/eyes/proc/refresh(call_update = TRUE)
if(ishuman(owner))
var/mob/living/carbon/human/affected_human = owner
// SKYRAT EDIT ADDITION
if (affected_human.emissive_eyes)
is_emissive = TRUE
// SKYRAT EDIT END
old_eye_color_left = affected_human.eye_color_left
old_eye_color_right = affected_human.eye_color_right
if(initial(eye_color_left))
affected_human.eye_color_left = eye_color_left
else
eye_color_left = affected_human.eye_color_left
if(initial(eye_color_right))
affected_human.eye_color_right = eye_color_right
else
eye_color_right = affected_human.eye_color_right
if(HAS_TRAIT(affected_human, TRAIT_NIGHT_VISION) && !lighting_alpha)
lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT
owner.update_tint()
owner.update_sight()
if(call_update && owner.has_dna() && ishuman(owner))
var/mob/living/carbon/human/affected_human = owner
affected_human.dna.species.handle_body(affected_human) //updates eye icon
owner.update_tint()
if(!ishuman(owner))
return
/obj/item/organ/internal/eyes/Remove(mob/living/carbon/eye_owner, special = 0)
var/mob/living/carbon/human/affected_human = owner
old_eye_color_left = affected_human.eye_color_left
old_eye_color_right = affected_human.eye_color_right
if(initial(eye_color_left))
affected_human.eye_color_left = eye_color_left
else
eye_color_left = affected_human.eye_color_left
if(initial(eye_color_right))
affected_human.eye_color_right = eye_color_right
else
eye_color_right = affected_human.eye_color_right
if(HAS_TRAIT(affected_human, TRAIT_NIGHT_VISION) && !lighting_alpha)
lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT
if(CONFIG_GET(flag/native_fov) && native_fov)
owner.add_fov_trait(type, native_fov)
// SKYRAT EDIT ADDITION - EMISSIVES
if (affected_human.emissive_eyes)
is_emissive = TRUE
// SKYRAT EDIT END
if(call_update)
owner.dna?.species?.handle_body(affected_human) //updates eye icon
/obj/item/organ/internal/eyes/Remove(mob/living/carbon/eye_owner, special = FALSE)
..()
if(ishuman(eye_owner))
var/mob/living/carbon/human/human_owner = eye_owner
@@ -103,11 +98,18 @@
human_owner.update_body()
if(native_fov)
eye_owner.remove_fov_trait(type)
// Cure blindness from eye damage
eye_owner.cure_blind(EYE_DAMAGE)
eye_owner.cure_nearsighted(EYE_DAMAGE)
eye_owner.set_blindness(0)
// Eye blind and temp blind go to, even if this is a bit of cheesy way to clear blindness
eye_owner.remove_status_effect(/datum/status_effect/eye_blur)
eye_owner.clear_fullscreen("eye_damage", 0)
eye_owner.remove_status_effect(/datum/status_effect/temporary_blindness)
// Then become blind anyways (if not special)
if(!special)
eye_owner.become_blind(NO_EYES)
eye_owner.update_tint()
eye_owner.update_sight()
is_emissive = FALSE // SKYRAT EDIT ADDITION
@@ -157,31 +159,44 @@
eye_color_left = initial(eye_color_left)
eye_color_right = initial(eye_color_right)
/obj/item/organ/internal/eyes/on_life(delta_time, times_fired)
/obj/item/organ/internal/eyes/applyOrganDamage(damage_amount, maximum, required_organtype)
. = ..()
var/mob/living/carbon/eye_owner = owner
//various degrees of "oh fuck my eyes", from "point a laser at your eye" to "staring at the Sun" intensities
if(damage > 20)
damaged = TRUE
if((organ_flags & ORGAN_FAILING))
eye_owner.become_blind(EYE_DAMAGE)
return
if(!owner)
return
apply_damaged_eye_effects()
var/obj/item/clothing/glasses/eyewear = eye_owner.glasses
var/has_prescription_glasses = istype(eyewear) && eyewear.vision_correction
if(has_prescription_glasses)
return
var/severity = damage > 30 ? 2 : 1
eye_owner.overlay_fullscreen("eye_damage", /atom/movable/screen/fullscreen/impaired, severity)
/// Applies effects to our owner based on how damaged our eyes are
/obj/item/organ/internal/eyes/proc/apply_damaged_eye_effects()
// we're in healthy threshold, either try to heal (if damaged) or do nothing
if(damage <= low_threshold)
if(damaged)
damaged = FALSE
// clear nearsightedness from damage
owner.cure_nearsighted(EYE_DAMAGE)
// if we're still nearsighted, reset its severity
// this is kinda icky, ideally we'd track severity to source but that's way more complex
var/datum/status_effect/grouped/nearsighted/nearsightedness = owner.is_nearsighted()
nearsightedness?.set_nearsighted_severity(1)
// and cure blindness from damage
owner.cure_blind(EYE_DAMAGE)
return
//called once since we don't want to keep clearing the screen of eye damage for people who are below 20 damage
if(damaged)
damaged = FALSE
eye_owner.clear_fullscreen("eye_damage")
eye_owner.cure_blind(EYE_DAMAGE)
//various degrees of "oh fuck my eyes", from "point a laser at your eye" to "staring at the Sun" intensities
// 50 - blind
// 49-31 - nearsighted (2 severity)
// 30-20 - nearsighted (1 severity)
if(organ_flags & ORGAN_FAILING)
// become blind from damage
owner.become_blind(EYE_DAMAGE)
else
// become nearsighted from damage
owner.become_nearsighted(EYE_DAMAGE)
// update the severity of our nearsightedness based on our eye damage
var/datum/status_effect/grouped/nearsighted/nearsightedness = owner.is_nearsighted()
nearsightedness.set_nearsighted_severity(damage > high_threshold ? 2 : 1)
damaged = TRUE
/obj/item/organ/internal/eyes/night_vision
see_in_dark = NIGHTVISION_FOV_RANGE
@@ -564,7 +579,7 @@
ADD_TRAIT(adapted, TRAIT_UNNATURAL_RED_GLOWY_EYES, ORGAN_TRAIT)
/obj/item/organ/internal/eyes/night_vision/maintenance_adapted/on_life(delta_time, times_fired)
if(!HAS_TRAIT(owner, TRAIT_BLIND) && isturf(owner.loc) && owner.has_light_nearby(light_amount=0.5)) //we allow a little more than usual so we can produce light from the adapted eyes
if(!owner.is_blind() && isturf(owner.loc) && owner.has_light_nearby(light_amount=0.5)) //we allow a little more than usual so we can produce light from the adapted eyes
to_chat(owner, span_danger("Your eyes! They burn in the light!"))
applyOrganDamage(10) //blind quickly
playsound(owner, 'sound/machines/grill/grillsizzle.ogg', 50)
+1
View File
@@ -88,6 +88,7 @@
#include "baseturfs.dm"
#include "bespoke_id.dm"
#include "binary_insert.dm"
#include "blindness.dm"
#include "bloody_footprints.dm"
#include "breath.dm"
#include "cable_powernets.dm"
+147
View File
@@ -0,0 +1,147 @@
#define HAS_SCREEN_OVERLAY(mob, type) (locate(type) in flatten_list(mob.screens))
#define HAS_CLIENT_COLOR(mob, type) (locate(type) in mob.client_colours)
/**
* Unit test to check that blindness adds the correct status effects, overlays, and client colors
*
* Also checks that blindness is added and removed correctly when it should and shouldn't be
*/
/datum/unit_test/blindness
/datum/unit_test/blindness/Run()
var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
var/obj/item/clothing/glasses/blindfold/blindfold = new(dummy.loc)
TEST_ASSERT(!dummy.is_blind(), "Dummy was blind on initialize, and shouldn't be.")
// Become blind
dummy.become_blind("unit_test")
check_if_blind(dummy)
// Cure their blindness immediately
dummy.cure_blind("unit_test")
check_if_not_blind(dummy)
// Become blindfolded, this one should blind us
dummy.equip_to_slot_if_possible(blindfold, ITEM_SLOT_EYES)
check_if_blind(dummy, status_message = "after being blindfolded")
// Become quirk blinded and mutation blindness, these shouldn't do anything since we're already blind
// Have to do a transfer here so we don't get a blindfold
var/datum/quirk/item_quirk/blindness/quirk = allocate(/datum/quirk/item_quirk/blindness)
quirk.add_to_holder(dummy, quirk_transfer = TRUE)
dummy.dna.add_mutation(/datum/mutation/human/blind)
// Remove the blindfold. We should remain blinded
QDEL_NULL(blindfold)
check_if_blind(dummy, status_message = "after removing their blindfold BUT still being blinded")
// Remove the quirk. We should remain blinded again
dummy.remove_quirk(/datum/quirk/item_quirk/blindness)
check_if_blind(dummy, status_message = "after removing their quirk BUT still being blinded")
// Remove the mutation, this should unblind us
dummy.dna.remove_mutation(/datum/mutation/human/blind)
check_if_not_blind(dummy, status_message = "after removing their blind mutation and having no sources of blindness left")
// Temp blindness
dummy.set_temp_blindness(10 SECONDS)
check_if_blind(dummy, status_message = "after being temporarily blinded")
// Now aheal, remove the temp blindness
dummy.fully_heal(ALL)
TEST_ASSERT(!dummy.has_status_effect(/datum/status_effect/temporary_blindness), "Dummy still had the temp blindness effect after being fullhealed.")
// Check that it worked out
check_if_not_blind(dummy, status_message = "after being ahealed while temporarily blinded")
/datum/unit_test/blindness/proc/check_if_blind(mob/living/carbon/human/dummy, status_message = "despite being made blind")
// Check for the status effect, duh
TEST_ASSERT(dummy.is_blind(), "Dummy, [status_message], did not have the blind status effect.")
// Being more technical, we need to check for client color and screen overlays
TEST_ASSERT(HAS_CLIENT_COLOR(dummy, /datum/client_colour/monochrome/blind), "Dummy, [status_message], did not have the monochrome client color.")
TEST_ASSERT(HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/blind), "Dummy, [status_message], did not have a blind screen overlay in their list of screens.")
/datum/unit_test/blindness/proc/check_if_not_blind(mob/living/carbon/human/dummy, status_message = "after being cured of blindness")
// Check for no status effect
TEST_ASSERT(!dummy.is_blind(), "Dummy, [status_message], still had the blindness status effect.")
// Check that the client color and screen overlay are gone
TEST_ASSERT(!HAS_CLIENT_COLOR(dummy, /datum/client_colour/monochrome/blind), "Dummy, [status_message], still had the monochrome client color.")
TEST_ASSERT(!HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/blind), "Dummy, [status_message], still had the blind sceen overlay.")
/**
* Unit test to check that nearsighted is added and disabled correctly
*/
/datum/unit_test/nearsightedness
/datum/unit_test/nearsightedness/Run()
var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
var/obj/item/clothing/glasses/regular/glasses = allocate(/obj/item/clothing/glasses/regular)
// Become quirk nearsighted
// Have to do a transfer here so we don't get glasses
var/datum/quirk/item_quirk/nearsighted/quirk = allocate(/datum/quirk/item_quirk/nearsighted)
quirk.add_to_holder(dummy, quirk_transfer = TRUE)
TEST_ASSERT(dummy.is_nearsighted(), "Dummy is not nearsighted after gaining the nearsighted quirk.")
TEST_ASSERT(HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy didn't gain the nearsighted overlay after becoming nearsighted.")
TEST_ASSERT(dummy.is_nearsighted_currently(), "Dummy is not currently nearsighted, after gaining the nearsighted quirk.")
// Become naturally nearsighted
dummy.become_nearsighted("unit_test")
// Equip the prescription glasses, they should disable nearsighted
dummy.equip_to_slot_if_possible(glasses, ITEM_SLOT_EYES)
TEST_ASSERT(dummy.is_nearsighted(), "Dummy was no longer nearsighted after putting on glasses. They should still be nearsighted, but it should be disabled.")
TEST_ASSERT(!HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy still had the nearsighted overlay, even though they were wearing glasses.")
TEST_ASSERT(!dummy.is_nearsighted_currently(), "Dummy was nearsighted currently even though they were wearing glasses.")
// Remove the glasses
QDEL_NULL(glasses)
TEST_ASSERT(HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy still had the nearsighted overlay, even though they were wearing glasses.")
TEST_ASSERT(dummy.is_nearsighted_currently(), "Dummy is not currently nearsighted, after removing their glasses.")
// And remove nearsightedness wholesale
dummy.remove_quirk(/datum/quirk/item_quirk/nearsighted)
dummy.cure_nearsighted("unit_test")
TEST_ASSERT(!dummy.is_nearsighted(), "Dummy is still nearsighted after being cured of it.")
TEST_ASSERT(!HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy still had the nearsighted overlay after being cured of it.")
/**
* Unit test to ensure eyes are properly blinded and nearsighted by eye damage
*/
/datum/unit_test/eye_damage
/datum/unit_test/eye_damage/Run()
var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
var/obj/item/organ/internal/eyes/eyes = dummy.getorganslot(ORGAN_SLOT_EYES)
TEST_ASSERT_NOTNULL(eyes, "Eye damage unit test spawned a dummy without eyes!")
// Test blindness due to eye damage
// Cause critical eye damage
var/critical_damage = eyes.maxHealth
eyes.setOrganDamage(critical_damage) // ~50 damage
TEST_ASSERT(dummy.is_blind(), "After sustaining critical eye damage ([critical_damage]), the dummy was not blind.")
// Heal eye damage
eyes.setOrganDamage(0)
TEST_ASSERT(!dummy.is_blind(), "After healing from critical eye damage, the dummy was not unblinded.")
// Test nearsightedness due to eye damage
var/datum/status_effect/grouped/nearsighted/nearsightedness
// Cause minor eye damage
var/minor_damage = eyes.maxHealth * 0.5
eyes.applyOrganDamage(minor_damage) //~25 ddamage
TEST_ASSERT(dummy.is_nearsighted(), "After sustaining minor eye damage ([minor_damage]), the dummy was not nearsighted.")
// Check that the severity is correct
nearsightedness = dummy.is_nearsighted()
TEST_ASSERT_EQUAL(nearsightedness.overlay_severity, 1, "After taking minor eye damage, the dummy's nearsightedness was the incorrect severity.")
nearsightedness = null
// Heal eye damage
eyes.setOrganDamage(0)
TEST_ASSERT(!dummy.is_nearsighted(), "After curing eye damage, the dummy was still nearsighted.")
// Cause major eye damage
var/major_damage = eyes.maxHealth * 0.7
eyes.applyOrganDamage(major_damage) //~35 damage
TEST_ASSERT(dummy.is_nearsighted(), "After sustaining major eye damage ([major_damage]), the dummy was not nearsighted.")
// Check that the severity is correct
nearsightedness = dummy.is_nearsighted()
TEST_ASSERT_EQUAL(nearsightedness.overlay_severity, 2, "After taking major eye damage, the dummy's nearsightedness was the incorrect severity.")
nearsightedness = null
// Heal eye damage
eyes.setOrganDamage(0)
TEST_ASSERT(!dummy.is_nearsighted(), "After curing eye damage, the dummy was still nearsighted.")
#undef HAS_SCREEN_OVERLAY
#undef HAS_CLIENT_COLOR
@@ -41,7 +41,7 @@
icon = 'modular_skyrat/master_files/icons/obj/clothing/glasses.dmi'
icon_state = "glasses_thin"
inhand_icon_state = "glasses"
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/betterunshit
name = "modern glasses"
@@ -50,7 +50,7 @@
icon = 'modular_skyrat/master_files/icons/obj/clothing/glasses.dmi'
icon_state = "glasses_alt"
inhand_icon_state = "glasses"
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/kim
name = "binoclard lenses"
@@ -59,7 +59,7 @@
icon = 'modular_skyrat/master_files/icons/obj/clothing/glasses.dmi'
icon_state = "binoclard_lenses"
inhand_icon_state = "glasses"
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/trickblindfold/hamburg
name = "thief visor"
@@ -76,7 +76,7 @@
icon = 'modular_skyrat/master_files/icons/obj/clothing/glasses.dmi'
icon_state = "biker"
inhand_icon_state = "welding-g"
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
// Like sunglasses, but without any protection
/obj/item/clothing/glasses/fake_sunglasses
@@ -28,7 +28,7 @@
if(!head)
to_chat(user, span_warning("[human_target] has no head!"))
return
if(human_target.is_mouth_covered(head_only = TRUE))
if(human_target.is_mouth_covered(ITEM_SLOT_HEAD))
to_chat(user, span_warning("You can't brush [human_target]'s hair while [human_target.p_their()] head is covered!"))
return
if(!do_after(user, brush_speed, human_target))
@@ -4,7 +4,7 @@
icon = 'modular_skyrat/modules/huds/icons/huds.dmi'
icon_state = "glasses_healthhud"
worn_icon = 'modular_skyrat/modules/huds/icons/hudeyes.dmi'
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/hud/diagnostic/prescription
name = "prescription diagnostic HUD"
@@ -12,7 +12,7 @@
icon = 'modular_skyrat/modules/huds/icons/huds.dmi'
icon_state = "glasses_diagnostichud"
worn_icon = 'modular_skyrat/modules/huds/icons/hudeyes.dmi'
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/hud/security/prescription
name = "prescription security HUD"
@@ -20,7 +20,7 @@
icon = 'modular_skyrat/modules/huds/icons/huds.dmi'
icon_state = "glasses_securityhud"
worn_icon = 'modular_skyrat/modules/huds/icons/hudeyes.dmi'
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/hud/science/prescription
name = "prescription science glasses"
@@ -28,7 +28,7 @@
icon = 'modular_skyrat/modules/huds/icons/huds.dmi'
icon_state = "glasses_sciencehud"
worn_icon = 'modular_skyrat/modules/huds/icons/hudeyes.dmi'
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
flash_protect = FLASH_PROTECTION_NONE
glass_colour_type = /datum/client_colour/glass_colour/purple
resistance_flags = ACID_PROOF
@@ -42,14 +42,14 @@
/obj/item/clothing/glasses/meson/prescription
name = "prescription optical meson scanner"
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions. This one has prescription lens fitted in."
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/meson/engine/prescription
name = "prescription engineering scanner goggles"
desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, the T-ray Scanner mode lets you see underfloor objects such as cables and pipes, and the Radiation Scanner mode let's you see objects contaminated by radiation. Each lens has been replaced with a corrective lens."
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/meson/engine/tray/prescription
name = "prescription optical t-ray scanner"
desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, the T-ray Scanner mode lets you see underfloor objects such as cables and pipes, and the Radiation Scanner mode let's you see objects contaminated by radiation. This one has a lens that help correct eye sight."
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
@@ -24,8 +24,6 @@ GLOBAL_LIST_INIT(loadout_glasses, generate_loadout_items(/datum/loadout_item/gla
equipper.update_glasses_color(equipped_glasses, TRUE)
if(equipped_glasses.tint)
equipper.update_tint()
if(equipped_glasses.vision_correction)
equipper.clear_fullscreen("nearsighted")
if(equipped_glasses.vision_flags \
|| equipped_glasses.darkness_view \
|| equipped_glasses.invis_override \
@@ -8,6 +8,8 @@
#define NIF_MINIMUM_DURABILITY 0
#define NIF_MINIMUM_POWER_LEVEL 0
#define NIF_SETUP_BLINDNESS "nif_setup"
// This is the original NIF that other NIFs are based on.
/obj/item/organ/internal/cyberimp/brain/nif
name = "Nanite Implant Framework"
@@ -267,9 +269,10 @@
var/percentage_done = (world.time - (calibration_duration - (calibration_time))) / calibration_time
switch(percentage_done)
if(NIF_CALIBRATION_STAGE_1 to NIF_CALIBRATION_STAGE_1_END)
linked_mob.set_blindness(5)
linked_mob.become_blind(NIF_SETUP_BLINDNESS)
if(NIF_CALIBRATION_STAGE_2 to NIF_CALIBRATION_STAGE_2_END)
linked_mob.cure_blind(NIF_SETUP_BLINDNESS)
var/random_ailment = rand(1, side_effect_risk)
switch(random_ailment)
if(1)
@@ -473,3 +476,4 @@
#undef NIF_DURABILITY_LOSS_HALVED
#undef NIF_MINIMUM_DURABILITY
#undef NIF_MINIMUM_POWER_LEVEL
#undef NIF_SETUP_BLINDNESS
@@ -160,27 +160,27 @@
/obj/item/clothing/glasses/hud/ar/aviator/security/prescription
name = "prescription security HUD aviators"
desc = "A heads-up display that scans the humanoids in view and provides accurate data about their ID status and security records. This HUD has been fitted inside of a pair of sunglasses with toggleable electrochromatic tinting which. Has lenses that help correct eye sight."
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/hud/ar/aviator/health/prescription
name = "prescription medical HUD aviators"
desc = "A heads-up display that scans the humanoids in view and provides accurate data about their health status. This HUD has been fitted inside of a pair of sunglasses which has lenses that help correct eye sight."
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/hud/ar/aviator/meson/prescription
name = "prescription meson HUD aviators"
desc = "A heads-up display used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions. This HUD has been fitted inside of a pair of sunglasses which has lenses that help correct eye sight."
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/hud/ar/aviator/diagnostic/prescription
name = "prescription diagnostic HUD aviators"
desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits. This HUD has been fitted inside of a pair of sunglasses which has lenses that help correct eye sight."
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
/obj/item/clothing/glasses/hud/ar/aviator/science/prescription
name = "prescription science aviators"
desc = "A pair of tacky purple aviator sunglasses that allow the wearer to recognize various chemical compounds with only a glance, which has lenses that help correct eye sight."
vision_correction = TRUE
clothing_traits = list(TRAIT_NEARSIGHTED_CORRECTED)
// Retinal projector
@@ -266,7 +266,7 @@
owner.clear_mood_event("sadistic")
/datum/brain_trauma/very_special/sadism/proc/someone_suffering()
if(HAS_TRAIT(owner, TRAIT_BLIND))
if(owner.is_blind())
return FALSE
for(var/mob/living/carbon/human/iterated_mob in oview(owner, 4))
if(!isliving(iterated_mob)) //ghosts ain't people
@@ -45,9 +45,9 @@
if(!iscarbon(user))
return
var/covered = ""
if(user.is_mouth_covered(head_only = 1))
if(user.is_mouth_covered(ITEM_SLOT_HEAD))
covered = "headgear"
else if(user.is_mouth_covered(mask_only = 1))
else if(user.is_mouth_covered(ITEM_SLOT_MASK))
covered = "mask"
if(covered)
to_chat(user, span_warning("You have to remove your [covered] first!"))
@@ -35,9 +35,9 @@
if(!iscarbon(user))
return
var/covered = ""
if(user.is_mouth_covered(head_only = 1))
if(user.is_mouth_covered(ITEM_SLOT_HEAD))
covered = "headgear"
else if(user.is_mouth_covered(mask_only = 1))
else if(user.is_mouth_covered(ITEM_SLOT_MASK))
covered = "mask"
if(covered)
to_chat(user, span_warning("You have to remove your [covered] first!"))
+2 -3
View File
@@ -1411,6 +1411,7 @@
#include "code\datums\status_effects\song_effects.dm"
#include "code\datums\status_effects\stacking_effect.dm"
#include "code\datums\status_effects\wound_effects.dm"
#include "code\datums\status_effects\debuffs\blindness.dm"
#include "code\datums\status_effects\debuffs\choke.dm"
#include "code\datums\status_effects\debuffs\confusion.dm"
#include "code\datums\status_effects\debuffs\debuffs.dm"
@@ -1421,6 +1422,7 @@
#include "code\datums\status_effects\debuffs\fire_stacks.dm"
#include "code\datums\status_effects\debuffs\hallucination.dm"
#include "code\datums\status_effects\debuffs\jitteriness.dm"
#include "code\datums\status_effects\debuffs\pacifism.dm"
#include "code\datums\status_effects\debuffs\screen_blur.dm"
#include "code\datums\status_effects\debuffs\screwy_hud.dm"
#include "code\datums\status_effects\debuffs\silenced.dm"
@@ -3823,7 +3825,6 @@
#include "code\modules\mob\living\brain\MMI.dm"
#include "code\modules\mob\living\brain\posibrain.dm"
#include "code\modules\mob\living\brain\skillchip.dm"
#include "code\modules\mob\living\brain\status_procs.dm"
#include "code\modules\mob\living\carbon\carbon.dm"
#include "code\modules\mob\living\carbon\carbon_context.dm"
#include "code\modules\mob\living\carbon\carbon_defense.dm"
@@ -3853,7 +3854,6 @@
#include "code\modules\mob\living\carbon\alien\logout.dm"
#include "code\modules\mob\living\carbon\alien\organs.dm"
#include "code\modules\mob\living\carbon\alien\screen.dm"
#include "code\modules\mob\living\carbon\alien\status_procs.dm"
#include "code\modules\mob\living\carbon\alien\adult\adult.dm"
#include "code\modules\mob\living\carbon\alien\adult\adult_defense.dm"
#include "code\modules\mob\living\carbon\alien\adult\adult_update_icons.dm"
@@ -3963,7 +3963,6 @@
#include "code\modules\mob\living\simple_animal\parrot.dm"
#include "code\modules\mob\living\simple_animal\shade.dm"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
#include "code\modules\mob\living\simple_animal\status_procs.dm"
#include "code\modules\mob\living\simple_animal\bot\bot.dm"
#include "code\modules\mob\living\simple_animal\bot\cleanbot.dm"
#include "code\modules\mob\living\simple_animal\bot\construction.dm"