[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
-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