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