From 541b4f7275a0b7e1616b20116f5adfd84cf81802 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Sat, 30 Dec 2017 00:20:34 -0500 Subject: [PATCH] Readability & Abstraction Improvements + A Tweak As per Tigercat's review, readability has been improved and the method by which eyeshine is applied has been abstracted a lot more. As part of that, I have divised a solution for the situation where, prior to this tweak, if you were a Tajara and had the 'bangs' hairstyle while also having eyeshine, one of your eyes would render ABOVE your hair. Now, despite the eye shine happening on a higher layer, the eye that would ordinarily be hidden by the hair still is. How? By cutting the pixels that are overlapped by the hair from the eye icon during rendering. --- code/__DEFINES/mob.dm | 1 + code/__HELPERS/icons.dm | 9 ++++++++ code/__HELPERS/unsorted.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 16 +++++++++---- .../mob/living/carbon/human/update_icons.dm | 14 ++++++++++- code/modules/surgery/organs/organ_internal.dm | 23 ++++++++++++++----- 6 files changed, 52 insertions(+), 13 deletions(-) diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm index 5312cba6e14..1b85e76c772 100644 --- a/code/__DEFINES/mob.dm +++ b/code/__DEFINES/mob.dm @@ -120,6 +120,7 @@ #define TINT_IMPAIR 2 //Threshold of tint level to apply weld mask overlay #define TINT_BLIND 3 //Threshold of tint level to obscure vision fully +#define EYE_SHINE_THRESHOLD 6 //dark_view threshold past which a humanoid's eyes will 'shine' in the dark. #define isliving(A) (istype((A), /mob/living)) #define iscarbon(A) (istype((A), /mob/living/carbon)) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index ac17d0591c5..96109186359 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -897,3 +897,12 @@ proc/rand_hex_color() for(var/i=0;i<6;i++) color = color+pick(colors) return "#[color]" + +//Imagine removing pixels from the main icon that are covered by pixels from the mask icon. +proc/get_icon_difference(var/icon/main, var/icon/mask) + if(istype(main) && istype(mask)) + mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible. + mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white. + mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white pixels. + main.AddAlphaMask(mask) //Make the pixels in the main icon that are in the transparent zone of the mask icon also vanish (fully transparent). + return main diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index f106d579e94..8be1eaa478b 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1337,7 +1337,7 @@ Standard way to write links -Sayu if(covered_locations & HEAD) return 0 if("eyes") - if(covered_locations & HEAD || face_covered & HIDEEYES || eyesmouth_covered & GLASSESCOVERSEYES) + if(face_covered & HIDEEYES || eyesmouth_covered & GLASSESCOVERSEYES || eyesmouth_covered & HEADCOVERSEYES) return 0 if("mouth") if(covered_locations & HEAD || face_covered & HIDEFACE || eyesmouth_covered & MASKCOVERSMOUTH) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 57d7cac79b5..030a022476d 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1668,12 +1668,18 @@ G.icon_state = "grabbed1" G.synch() -/mob/living/carbon/human/proc/eyes_shine() /*Used to check if eyes should shine in the dark. Returns the image of the eyes on the layer where they will appear to shine. - Eyes need to have significantly high darksight to shine unless the mob has the XRAY vision mutation. Eyes will not shine if they are covered in any way.*/ +/*Used to check if eyes should shine in the dark. Returns the image of the eyes on the layer where they will appear to shine. +Eyes need to have significantly high darksight to shine unless the mob has the XRAY vision mutation. Eyes will not shine if they are covered in any way.*/ +/mob/living/carbon/human/proc/eyes_shine() var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) - var/const/shine_threshold = 6 - if(istype(eyes) && ((eyes.get_dark_view() > shine_threshold) || (XRAY in mutations)) && get_location_accessible(src, "eyes")) - return(image(eyes.generate_icon(), layer = LIGHTING_LAYER + 1)) //Referenced cult constructs for shining in the dark. Needs to be above lighting effects such as shading. + if(!istype(eyes)) + return FALSE + if(!(eyes.get_dark_view() > EYE_SHINE_THRESHOLD) && !(XRAY in mutations)) + return FALSE + if(!get_location_accessible(src, "eyes")) + return FALSE + + return TRUE /mob/living/carbon/human/proc/gut() set category = "Abilities" diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 77074bee3f6..26805d4e791 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -105,6 +105,7 @@ Please contact me on #coderbus IRC. ~Carn x /mob/living/carbon/human var/list/overlays_standing[TOTAL_LAYERS] + var/list/misc_effect_overlays = list() //Overlays that are applied at a custom layer (defined in each image's .layer property) outside of standard overlay application. Updated in update_misc_effects() var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed var/icon/skeleton var/list/cached_standing_overlays = list() // List of everything currently in a human's actual overlays @@ -154,13 +155,16 @@ Please contact me on #coderbus IRC. ~Carn x I.layer = (-2 - (TOTAL_LAYERS - i)) // Highest layer gets -2, each prior layer is 1 lower new_overlays += I + update_misc_effects() + if(misc_effect_overlays) + new_overlays += misc_effect_overlays + if(frozen) // Admin freeze overlay new_overlays += frozen overlays += (new_overlays - old_overlays) overlays -= (old_overlays - new_overlays) cached_standing_overlays = new_overlays - overlays |= eyes_shine() //Only applies eyeshine if the eyes are uncovered and have significantly high darksight or XRAY vision. update_transform() @@ -1325,6 +1329,14 @@ var/global/list/damage_icon_parts = list() if(update_icons) update_icons() +/mob/living/carbon/human/proc/update_misc_effects() + misc_effect_overlays.Cut() + + //Begin appending miscellaneous effects. + if(eyes_shine()) + var/obj/item/organ/internal/eyes/E = get_int_organ(/obj/item/organ/internal/eyes) + misc_effect_overlays += E.get_eye_shine() //Image layer is specified in get_eye_shine() proc as LIGHTING_LAYER + 1. + /mob/living/carbon/human/proc/force_update_limbs() for(var/obj/item/organ/external/O in bodyparts) O.sync_colour_to_human(src) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 6114ae57ed1..b1adcce9ae8 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -305,12 +305,23 @@ /obj/item/organ/internal/eyes/proc/update_colour() dna.write_eyes_attributes(src) -/obj/item/organ/internal/eyes/proc/generate_icon(var/mob/living/carbon/human/H) - var/mob/living/carbon/human/G = H ? H : owner - if(istype(G)) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', G.species.eyes) - eyes_icon.Blend(eye_colour, ICON_ADD) - return(eyes_icon) +/obj/item/organ/internal/eyes/proc/generate_icon(var/mob/living/carbon/human/HA) + var/mob/living/carbon/human/H = HA + if(!istype(H)) + H = owner + var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', H.species.eyes) + eyes_icon.Blend(eye_colour, ICON_ADD) + return eyes_icon + +/obj/item/organ/internal/eyes/proc/get_eye_shine(var/mob/living/carbon/human/HA) //Referenced cult constructs for shining in the dark. Needs to be above lighting effects such as shading. + var/mob/living/carbon/human/H = HA + if(!istype(H)) + H = owner + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + var/datum/sprite_accessory/hair/hair_style = hair_styles_full_list[head_organ.h_style] + var/icon/hair = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") + + return image(get_icon_difference(generate_icon(H), hair), layer = LIGHTING_LAYER + 1) //Cut the hair's pixels from the eyes icon so eyes covered by bangs stay hidden even while on a higher layer. /obj/item/organ/internal/eyes/proc/get_colourmatrix() //Returns a special colour matrix if the eyes are organic and the mob is colourblind, otherwise it uses the current one. if(!robotic && owner.disabilities & COLOURBLIND)