Merge pull request #16172 from dearmochi/hair-gradients

[READY] Port hair gradient customization
This commit is contained in:
Fox McCloud
2021-11-11 15:40:21 -05:00
committed by GitHub
21 changed files with 260 additions and 41 deletions
@@ -153,6 +153,12 @@
else
//this shouldn't happen
H.h_style = "Bald"
// Gradient
H.h_grad_style = "None"
H.h_grad_offset_x = 0
H.h_grad_offset_y = 0
H.h_grad_colour = "#000000"
H.h_grad_alpha = 255
update_hair()
@@ -310,6 +316,25 @@
update_body()
return 1
/mob/living/carbon/human/proc/change_hair_gradient(style, offset_raw, color, alpha)
var/obj/item/organ/external/head/H = get_organ("head")
if(!H)
return
if(!isnull(style))
H.h_grad_style = style
if(!isnull(offset_raw))
var/list/expl = splittext(offset_raw, ",")
if(length(expl) == 2)
H.h_grad_offset_x = clamp(text2num(expl[1]) || 0, -16, 16)
H.h_grad_offset_y = clamp(text2num(expl[2]) || 0, -16, 16)
if(!isnull(color))
H.h_grad_colour = color
if(!isnull(alpha))
H.h_grad_alpha = clamp(alpha, 0, 255)
update_hair()
/mob/living/carbon/human/proc/update_dna()
check_dna()
dna.ready_dna(src)
@@ -354,49 +354,54 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
else
//warning("Invalid ha_style for [species.name]: [ha_style]")
//HAIR OVERLAY
/**
* Generates overlays for the hair layer.
*/
/mob/living/carbon/human/proc/update_hair()
//Reset our hair
remove_overlay(HAIR_LAYER)
var/obj/item/organ/external/head/head_organ = get_organ("head")
if(!head_organ)
var/obj/item/organ/external/head/O = get_organ("head")
if(!O)
return
//masks and helmets can obscure our hair, unless we're a synthetic
if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
if((head?.flags & BLOCKHAIR) || (wear_mask?.flags & BLOCKHAIR))
return
//base icons
var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(ismachineperson(src))))
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
if(hair_style && hair_style.species_allowed)
if((head_organ.dna.species.name in hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
if(istype(head_organ.dna.species, /datum/species/slime)) // I am el worstos
hair_s.Blend("[skin_colour]A0", ICON_AND)
else if(hair_style.do_colouration)
hair_s.Blend(head_organ.hair_colour, ICON_ADD)
var/mutable_appearance/MA = new()
MA.appearance_flags = KEEP_TOGETHER
MA.layer = -HAIR_LAYER
if(O.h_style && !(head?.flags & BLOCKHEADHAIR) && !ismachineperson(src))
var/datum/sprite_accessory/hair/hair = GLOB.hair_styles_full_list[O.h_style]
if(hair?.species_allowed && ((O.dna.species.name in hair.species_allowed) || (O.dna.species.bodyflags & ALL_RPARTS)))
// Base hair
var/mutable_appearance/img_hair = mutable_appearance(hair.icon, "[hair.icon_state]_s")
if(istype(O.dna.species, /datum/species/slime))
img_hair.color = COLOR_MATRIX_OVERLAY("[skin_colour]A0")
else if(hair.do_colouration)
img_hair.color = COLOR_MATRIX_ADD(O.hair_colour)
MA.overlays += img_hair
if(hair_style.secondary_theme)
var/icon/hair_secondary_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_[hair_style.secondary_theme]_s")
if(!hair_style.no_sec_colour)
hair_secondary_s.Blend(head_organ.sec_hair_colour, ICON_ADD)
hair_s.Blend(hair_secondary_s, ICON_OVERLAY)
// Gradient
var/datum/sprite_accessory/hair_gradient/gradient = GLOB.hair_gradients_list[O.h_grad_style]
if(gradient)
var/mutable_appearance/img_gradient = mutable_appearance(gradient.icon, gradient.icon_state)
img_gradient.alpha = O.h_grad_alpha
img_gradient.color = COLOR_MATRIX_OVERLAY(O.h_grad_colour)
img_gradient.pixel_x = O.h_grad_offset_x
img_gradient.pixel_y = O.h_grad_offset_y
img_gradient.blend_mode = BLEND_INSET_OVERLAY
MA.overlays += img_gradient
hair_standing = hair_s //hair_standing.Blend(hair_s, ICON_OVERLAY)
//Having it this way preserves animations. Useful for IPC screens.
else
//warning("Invalid h_style for [species.name]: [h_style]")
//hair_standing.Blend(debrained_s, ICON_OVERLAY)//how does i overlay for fish?
// Secondary style
if(hair.secondary_theme)
var/mutable_appearance/img_secondary = mutable_appearance(hair.icon, "[hair.icon_state]_[hair.secondary_theme]_s")
if(!hair.no_sec_colour)
img_secondary.color = COLOR_MATRIX_ADD(O.sec_hair_colour)
MA.overlays += img_secondary
overlays_standing[HAIR_LAYER] = mutable_appearance(hair_standing, layer = -HAIR_LAYER)
overlays_standing[HAIR_LAYER] = MA
apply_overlay(HAIR_LAYER)
//FACIAL HAIR OVERLAY
/mob/living/carbon/human/proc/update_fhair()
//Reset our facial hair
@@ -648,3 +648,48 @@
/datum/sprite_accessory/socks/stockings_blue
name = "Stockings (Blue)"
icon_state = "stockings_blue"
/* HAIR GRADIENT */
/datum/sprite_accessory/hair_gradient
icon = 'icons/mob/hair_gradients.dmi'
/datum/sprite_accessory/hair_gradient/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/hair_gradient/fadeup
name = "Fade Up"
icon_state = "fadeup"
/datum/sprite_accessory/hair_gradient/fadedown
name = "Fade Down"
icon_state = "fadedown"
/datum/sprite_accessory/hair_gradient/vertical_split
name = "Vertical Split"
icon_state = "vsplit"
/datum/sprite_accessory/hair_gradient/_split
name = "Horizontal Split"
icon_state = "bottomflat"
/datum/sprite_accessory/hair_gradient/reflected
name = "Reflected"
icon_state = "reflected_high"
/datum/sprite_accessory/hair_gradient/reflected_inverse
name = "Reflected Inverse"
icon_state = "reflected_inverse_high"
/datum/sprite_accessory/hair_gradient/wavy
name = "Wavy"
icon_state = "wavy"
/datum/sprite_accessory/hair_gradient/long_fade_up
name = "Long Fade Up"
icon_state = "long_fade_up"
/datum/sprite_accessory/hair_gradient/long_fade_down
name = "Long Fade Down"
icon_state = "long_fade_down"