From 5b20a67ed2d6a26433bcd474895d012281dedf6e Mon Sep 17 00:00:00 2001 From: KasparoVy <12377767+KasparoVy@users.noreply.github.com> Date: Wed, 28 Aug 2019 04:58:23 -0400 Subject: [PATCH] Fixes Bugs Darkening Glowing Eyes & Preventing Full Rendering of Disembodied Heads, Cleanup By correcting the plane the eye shine is rendered on. By sharing the same plane as the lighting, the eye shine was getting dimmed slightly (somehow). Referred to Polaris codebase, where this was originally ported from. Lumps in an update/write-up for get_icon_difference() Cleans up organ_icon.dm and resolves an issue preventing appearance overlays (hair, eyes, etc.) from remaining on disembodied heads to reduce unnecessary icon operations. --- code/__HELPERS/icons.dm | 16 +++-- code/modules/mob/living/carbon/human/human.dm | 10 +-- code/modules/surgery/organs/organ_icon.dm | 72 +++++++++---------- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index ed4f3242c4d..0b37872decd 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -948,10 +948,16 @@ The _flatIcons list is a cache for generated icon files. 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) +//Standard behaviour is to cut pixels from the main icon that are covered by pixels from the mask icon unless passed mask_ready, see below. +/proc/get_icon_difference(var/icon/main, var/icon/mask, var/mask_ready) + /*You should skip prep if the mask is already sprited properly. This significantly improves performance by eliminating most of the realtime icon work. + e.g. A 'ready' mask is a mask where the part you want cut out is missing (no pixels, 0 alpha) from the sprite, and everything else is solid white.*/ + 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. + if(!mask_ready) //Prep the mask if we're using a regular old sprite and not a special-made 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 background 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 + return main \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0cd4b176e0b..78b51cd2556 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -849,7 +849,7 @@ return var/read = 0 var/perpname = get_visible_name(TRUE) - + for(var/datum/data/record/E in data_core.general) if(E.fields["name"] == perpname) for(var/datum/data/record/R in data_core.medical) @@ -1470,12 +1470,12 @@ var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) var/obj/item/organ/internal/cyberimp/eyes/eye_implant = get_int_organ(/obj/item/organ/internal/cyberimp/eyes) if(istype(dna.species) && dna.species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', dna.species.eyes) + var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', dna.species.eyes) if(eye_implant) //Eye implants override native DNA eye colo(u)r eyes_icon = eye_implant.generate_icon() else if(eyes) eyes_icon = eyes.generate_icon() - else + else //Error 404: Eyes not found! eyes_icon.Blend("#800000", ICON_ADD) return eyes_icon @@ -1484,8 +1484,8 @@ var/obj/item/organ/external/head/head_organ = get_organ("head") var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style] var/icon/hair = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - var/mutable_appearance/MA = mutable_appearance(get_icon_difference(get_eyecon(), hair), layer = LIGHTING_LAYER + 1) - MA.plane = LIGHTING_PLANE + var/mutable_appearance/MA = mutable_appearance(get_icon_difference(get_eyecon(), hair), layer = ABOVE_LIGHTING_LAYER) + MA.plane = ABOVE_LIGHTING_PLANE return MA //Cut the hair's pixels from the eyes icon so eyes covered by bangs stay hidden even while on a higher layer. /*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. diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index f291f61c96d..5a4a1e483e7 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -87,67 +87,67 @@ var/global/list/limb_icon_cache = list() else if(s_col) mob_icon.Blend(s_col, ICON_ADD) + if(owner) //Maintains overlays on disembodied parts. + cut_overlays() + dir = EAST icon = mob_icon return mob_icon /obj/item/organ/external/head/get_icon() - ..() - overlays.Cut() if(!owner) return if(dna.species.has_organ["eyes"]) var/icon/eyes_icon = owner.get_eyecon() if(eyes_icon) - mob_icon.Blend(eyes_icon, ICON_OVERLAY) - overlays |= eyes_icon + add_overlay(eyes_icon) if(owner.lip_style && (LIPS in dna.species.species_traits)) - var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") - overlays |= lip_icon - mob_icon.Blend(lip_icon, ICON_OVERLAY) + add_overlay(mutable_appearance('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s")) //Hefty icon not necessary. var/head_marking = owner.m_styles["head"] - if(head_marking && head_marking != "None") + if(head_marking) var/datum/sprite_accessory/head_marking_style = GLOB.marking_styles_list[head_marking] if(head_marking_style && head_marking_style.species_allowed && (dna.species.name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") - var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") + var/icon/h_marking_s = new /icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(owner.m_colours["head"], ICON_ADD) - overlays |= h_marking_s + add_overlay(h_marking_s) - if(ha_style) - var/datum/sprite_accessory/head_accessory_style = GLOB.head_accessory_styles_list[ha_style] - if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) - var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") - if(head_accessory_style.do_colouration) - head_accessory_s.Blend(headacc_colour, ICON_ADD) - overlays |= head_accessory_s + if(!((owner.head && (owner.head.flags & BLOCKHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHAIR)))) //Common restriction for all the below features. + if(ha_style) + var/datum/sprite_accessory/head_accessory_style = GLOB.head_accessory_styles_list[ha_style] + if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) + var/icon/head_accessory_s = new /icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") + if(head_accessory_style.do_colouration) + head_accessory_s.Blend(headacc_colour, ICON_ADD) + add_overlay(head_accessory_s) - if(f_style) - var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) - var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(istype(dna.species, /datum/species/slime)) // I am el worstos - facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. - else if(facial_hair_style.do_colouration) - facial_s.Blend(facial_colour, ICON_ADD) - overlays |= facial_s + if(f_style) + var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] + if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) + var/icon/facial_s = new /icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") + if(istype(dna.species, /datum/species/slime)) // I am el worstos + facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. + else if(facial_hair_style.do_colouration) + facial_s.Blend(facial_colour, ICON_ADD) + add_overlay(facial_s) - if(h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair_style = GLOB.hair_styles_full_list[h_style] - if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) - var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(istype(dna.species, /datum/species/slime)) // I am el worstos - hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. - else if(hair_style.do_colouration) - hair_s.Blend(hair_colour, ICON_ADD) - overlays |= hair_s + if(h_style) + if(!owner.isSynthetic() || (owner.isSynthetic() && ((owner.head && (owner.head.flags & BLOCKHEADHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHEADHAIR))))) + var/datum/sprite_accessory/hair_style = GLOB.hair_styles_full_list[h_style] + if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) + var/icon/hair_s = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") + if(istype(dna.species, /datum/species/slime)) // I am el worstos + hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. + else if(hair_style.do_colouration) + hair_s.Blend(hair_colour, ICON_ADD) + add_overlay(hair_s) - return mob_icon + return mob_icon //Don't need to blend the above into this as it's handled in human/update_icons(). The overlays are for rendering stuff on disembodied heads. /obj/item/organ/external/proc/get_icon_state(skeletal) var/gender