SPECIES NUKING 2023: Refactors a bunch of species traits into flags for the head bodypart (#76074)

## About The Pull Request

Title. 
I saw a comment on psyker code complaining about these species traits
(which admittedly, they suck) and heeded the call to turn all of this
crap into something defined almost entirely by the head bodypart.

## Why It's Good For The Game

Potential to simplify species code further in the future, by delegating
more visuals to bodyparts, which is where most of them should be
handled.

## Changelog

Should not be player facing, unless I fucked up.

---------

Co-authored-by: Time-Green <timkoster1@hotmail.com>
This commit is contained in:
ChungusGamer666
2023-06-22 05:23:19 -03:00
committed by GitHub
parent 866a06a248
commit f030b3b5aa
51 changed files with 494 additions and 440 deletions
@@ -7,7 +7,11 @@
examine_limb_id = SPECIES_SHADOW
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE
no_equip_flags = ITEM_SLOT_MASK | ITEM_SLOT_OCLOTHING | ITEM_SLOT_GLOVES | ITEM_SLOT_FEET | ITEM_SLOT_ICLOTHING | ITEM_SLOT_SUITSTORE
species_traits = list(NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYESPRITES)
species_traits = list(
NO_UNDERWEAR,
NO_DNA_COPY,
NOTRANSSTING,
)
inherent_traits = list(
TRAIT_ADVANCEDTOOLUSER,
TRAIT_CAN_STRIP,
@@ -109,6 +109,10 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
/// will show the feature as selectable.
var/relevant_external_organ = null
/// If the selected species has this head_flag by default,
/// will show the feature as selectable.
var/relevant_head_flag = null
/// Called on the saved input when retrieving.
/// Also called by the value sent from the user through UI. Do not trust it.
/// Input is the value inside the savefile, output is to tell other code
@@ -26,7 +26,7 @@
savefile_key = "eye_color"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
relevant_species_trait = EYECOLOR
relevant_head_flag = HEAD_EYECOLOR
/datum/preference/color/eye_color/apply_to_human(mob/living/carbon/human/target, value)
var/hetero = target.eye_color_heterochromatic
@@ -59,7 +59,7 @@
category = PREFERENCE_CATEGORY_FEATURES
main_feature_name = "Facial hair"
should_generate_icons = TRUE
relevant_species_trait = FACEHAIR
relevant_head_flag = HEAD_FACIAL_HAIR
/datum/preference/choiced/facial_hairstyle/init_possible_values()
return generate_possible_values_for_sprite_accessories_on_head(GLOB.facial_hairstyles_list)
@@ -79,7 +79,7 @@
savefile_key = "facial_hair_color"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES
relevant_species_trait = FACEHAIR
relevant_head_flag = HEAD_FACIAL_HAIR
/datum/preference/color/facial_hair_color/apply_to_human(mob/living/carbon/human/target, value)
target.facial_hair_color = value
@@ -89,7 +89,7 @@
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
savefile_identifier = PREFERENCE_CHARACTER
savefile_key = "facial_hair_gradient"
relevant_species_trait = FACEHAIR
relevant_head_flag = HEAD_FACIAL_HAIR
/datum/preference/choiced/facial_hair_gradient/init_possible_values()
return assoc_to_keys_features(GLOB.facial_hair_gradients_list)
@@ -106,7 +106,7 @@
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
savefile_identifier = PREFERENCE_CHARACTER
savefile_key = "facial_hair_gradient_color"
relevant_species_trait = FACEHAIR
relevant_head_flag = HEAD_FACIAL_HAIR
/datum/preference/color/facial_hair_gradient/apply_to_human(mob/living/carbon/human/target, value)
LAZYSETLEN(target.grad_color, GRADIENTS_LEN)
@@ -122,7 +122,7 @@
savefile_key = "hair_color"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES
relevant_species_trait = HAIR
relevant_head_flag = HEAD_HAIR
/datum/preference/color/hair_color/apply_to_human(mob/living/carbon/human/target, value)
target.hair_color = value
@@ -133,7 +133,7 @@
category = PREFERENCE_CATEGORY_FEATURES
main_feature_name = "Hairstyle"
should_generate_icons = TRUE
relevant_species_trait = HAIR
relevant_head_flag = HEAD_HAIR
/datum/preference/choiced/hairstyle/init_possible_values()
return generate_possible_values_for_sprite_accessories_on_head(GLOB.hairstyles_list)
@@ -152,7 +152,7 @@
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
savefile_identifier = PREFERENCE_CHARACTER
savefile_key = "hair_gradient"
relevant_species_trait = HAIR
relevant_head_flag = HEAD_HAIR
/datum/preference/choiced/hair_gradient/init_possible_values()
return assoc_to_keys_features(GLOB.hair_gradients_list)
@@ -169,7 +169,7 @@
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
savefile_identifier = PREFERENCE_CHARACTER
savefile_key = "hair_gradient_color"
relevant_species_trait = HAIR
relevant_head_flag = HEAD_HAIR
/datum/preference/color/hair_gradient/apply_to_human(mob/living/carbon/human/target, value)
LAZYSETLEN(target.grad_color, GRADIENTS_LEN)
+5 -1
View File
@@ -70,6 +70,10 @@
if((head.flags_inv & HIDEHAIR) && !istype(head, /obj/item/clothing/head/wig))
to_chat(user, span_warning("You can't get a good look at [target.p_their()] hair!"))
return
var/obj/item/bodypart/head/noggin = target.get_bodypart(BODY_ZONE_HEAD)
if(!noggin)
to_chat(user, span_warning("[target.p_they(TRUE)] have no head!"))
return
var/selected_hairstyle = null
var/selected_hairstyle_color = null
@@ -77,7 +81,7 @@
var/obj/item/clothing/head/wig/wig = target.head
selected_hairstyle = wig.hairstyle
selected_hairstyle_color = wig.color
else if((HAIR in target.dna.species.species_traits) && target.hairstyle != "Bald")
else if((noggin.head_flags & HEAD_HAIR) && target.hairstyle != "Bald")
selected_hairstyle = target.hairstyle
selected_hairstyle_color = "[target.hair_color]"
+1 -1
View File
@@ -66,7 +66,7 @@
inhand_icon_state = "tapehat"
dog_fashion = null
worn_y_offset = 6
body_parts_covered = HEAD|HAIR
body_parts_covered = HEAD //this used to also cover HAIR, but that was never valid code as HAIR is not actually a body_part define!
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
/obj/item/clothing/head/wizard/magus
@@ -242,8 +242,8 @@
var/mob/living/carbon/human/head_species_source = new
head_species_source.set_species(/datum/species/skeleton)
head_species_source.real_name = "spaced locker victim"
var/obj/item/bodypart/head/skeleton_head = new
skeleton_head.update_limb(FALSE,head_species_source)
var/obj/item/bodypart/head/skeleton_head = head_species_source.get_bodypart(BODY_ZONE_HEAD)
skeleton_head.drop_limb(FALSE)
qdel(head_species_source)
drone.try_transfer(skeleton_head)
@@ -62,7 +62,7 @@
* Currently only used by mutantparts so don't worry about hair and stuff.
* This is the source that this accessory will get its color from. Default is MUTCOLOR, but can also be HAIR, FACEHAIR, EYECOLOR and 0 if none.
*/
var/color_src = MUTCOLORS
var/color_src = MUTANT_COLOR
/// Decides if this sprite has an "inner" part, such as the fleshy parts on ears.
var/hasinner = FALSE
/// Is this part locked from roundstart selection? Used for parts that apply effects.
@@ -1767,7 +1767,7 @@
name = "Cat"
icon = 'icons/mob/species/human/cat_features.dmi'
icon_state = "default"
color_src = HAIR
color_src = HAIR_COLOR
/datum/sprite_accessory/tails/monkey
name = "Monkey"
@@ -1879,14 +1879,14 @@
name = "Cat"
icon_state = "cat"
hasinner = TRUE
color_src = HAIR
color_src = HAIR_COLOR
/datum/sprite_accessory/ears/fox
icon = 'icons/mob/species/human/fox_features.dmi'
name = "Fox"
icon_state = "fox"
hasinner = TRUE
color_src = HAIR
color_src = HAIR_COLOR
locked = TRUE
/datum/sprite_accessory/wings/none
@@ -2105,7 +2105,7 @@
/datum/sprite_accessory/caps
icon = 'icons/mob/species/mush_cap.dmi'
color_src = HAIR
color_src = HAIR_COLOR
em_block = TRUE
/datum/sprite_accessory/caps/round
+5 -5
View File
@@ -106,10 +106,11 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
if(ishuman(body))
var/mob/living/carbon/human/body_human = body
if(HAIR in body_human.dna.species.species_traits)
var/datum/species/human_species = body_human.dna.species
if(human_species.check_head_flags(HEAD_HAIR))
hairstyle = body_human.hairstyle
hair_color = brighten_color(body_human.hair_color)
if(FACEHAIR in body_human.dna.species.species_traits)
if(human_species.check_head_flags(HEAD_FACIAL_HAIR))
facial_hairstyle = body_human.facial_hairstyle
facial_hair_color = brighten_color(body_human.facial_hair_color)
@@ -827,12 +828,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/species_type = client.prefs.read_preference(/datum/preference/choiced/species)
var/datum/species/species = new species_type
if(HAIR in species.species_traits)
if(species.check_head_flags(HEAD_HAIR))
hairstyle = client.prefs.read_preference(/datum/preference/choiced/hairstyle)
hair_color = brighten_color(client.prefs.read_preference(/datum/preference/color/hair_color))
if(FACEHAIR in species.species_traits)
if(species.check_head_flags(HEAD_FACIAL_HAIR))
facial_hairstyle = client.prefs.read_preference(/datum/preference/choiced/facial_hairstyle)
facial_hair_color = brighten_color(client.prefs.read_preference(/datum/preference/color/facial_hair_color))
@@ -599,29 +599,46 @@
/obj/item/bodypart/head/generate_icon_key()
. = ..()
. += "-[facial_hairstyle]"
. += "-[facial_hair_color]"
if(facial_hair_gradient_style)
. += "-[facial_hair_gradient_style]"
if(hair_gradient_color)
. += "-[facial_hair_gradient_color]"
if(lip_style)
. += "-[lip_style]"
. += "-[lip_color]"
if(facial_hair_hidden)
. += "-FACIAL_HAIR_HIDDEN"
else
. += "-[facial_hairstyle]"
. += "-[override_hair_color || fixed_hair_color || facial_hair_color]"
. += "-[facial_hair_alpha]"
if(facial_hair_gradient_style)
. += "-[facial_hair_gradient_style]"
. += "-[facial_hair_gradient_color]"
if(show_missing_eyes)
. += "-SHOW_MISSING_EYES"
if(show_debrained)
. += "-SHOW_DEBRAINED"
return .
. += "-[hair_style]"
. += "-[fixed_hair_color || override_hair_color || hair_color]"
if(hair_gradient_style)
. += "-[hair_gradient_style]"
if(hair_gradient_color)
. += "-[hair_gradient_color]"
if(hair_hidden)
. += "-HAIR_HIDDEN"
else
. += "-[hair_style]"
. += "-[override_hair_color || fixed_hair_color || hair_color]"
. += "-[hair_alpha]"
if(hair_gradient_style)
. += "-[hair_gradient_style]"
. += "-[hair_gradient_color]"
return .
/obj/item/bodypart/head/generate_husk_key()
. = ..()
if(show_missing_eyes)
. += "-SHOW_MISSING_EYES"
if(show_debrained)
. += "-SHOW_DEBRAINED"
return .
GLOBAL_LIST_EMPTY(masked_leg_icons_cache)
/**
@@ -32,6 +32,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
var/hair_color
///The alpha used by the hair. 255 is completely solid, 0 is invisible.
var/hair_alpha = 255
///The alpha used by the facial hair. 255 is completely solid, 0 is invisible.
var/facial_hair_alpha = 255
///This is used for children, it will determine their default limb ID for use of examine. See [/mob/living/carbon/human/proc/examine].
var/examine_limb_id
@@ -180,9 +182,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
///List of results you get from knife-butchering. null means you cant butcher it. Associated by resulting type - value of amount
var/list/knife_butcher_results
///List of visual overlays created by handle_body()
var/list/body_vis_overlays = list()
/// Should we preload this species's organs?
var/preload = TRUE
@@ -610,53 +609,25 @@ GLOBAL_LIST_EMPTY(features_by_species)
return handle_mutant_bodyparts(species_human)
var/list/standing = list()
var/obj/item/bodypart/head/noggin = species_human.get_bodypart(BODY_ZONE_HEAD)
if(noggin && !(HAS_TRAIT(species_human, TRAIT_HUSK)))
// lipstick
if(species_human.lip_style && (LIPS in species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/species/human/human_face.dmi', "lips_[species_human.lip_style]", -BODY_LAYER)
lip_overlay.color = species_human.lip_color
noggin.worn_face_offset?.apply_offset(lip_overlay)
lip_overlay.pixel_y += height_offset
standing += lip_overlay
// eyes
if(!(NOEYESPRITES in species_traits))
if(!HAS_TRAIT(species_human, TRAIT_HUSK))
var/obj/item/bodypart/head/noggin = species_human.get_bodypart(BODY_ZONE_HEAD)
if(noggin?.head_flags & HEAD_EYESPRITES)
// eyes (missing eye sprites get handled by the head itself, but sadly we have to do this stupid shit here, for now)
var/obj/item/organ/internal/eyes/eye_organ = species_human.get_organ_slot(ORGAN_SLOT_EYES)
var/mutable_appearance/no_eyeslay
var/add_pixel_x = 0
var/add_pixel_y = 0
//cut any possible vis overlays
if(body_vis_overlays.len)
SSvis_overlays.remove_vis_overlay(species_human, body_vis_overlays)
var/list/feature_offset = noggin.worn_face_offset?.get_offset()
if(feature_offset)
add_pixel_x = feature_offset["x"]
add_pixel_y = feature_offset["y"]
add_pixel_y += height_offset
if(eye_organ)
eye_organ.refresh(call_update = FALSE)
for(var/mutable_appearance/eye_overlay in eye_organ.generate_body_overlay(species_human))
eye_overlay.pixel_y += height_offset
standing += eye_overlay
else if (!(NOEYEHOLES in species_traits))
no_eyeslay = mutable_appearance('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER)
no_eyeslay.pixel_x += add_pixel_x
no_eyeslay.pixel_y += add_pixel_y
standing += no_eyeslay
// organic body markings
if(HAS_MARKINGS in species_traits)
var/obj/item/bodypart/chest/chest = species_human.get_bodypart(BODY_ZONE_CHEST)
var/obj/item/bodypart/arm/right/right_arm = species_human.get_bodypart(BODY_ZONE_R_ARM)
var/obj/item/bodypart/arm/left/left_arm = species_human.get_bodypart(BODY_ZONE_L_ARM)
var/obj/item/bodypart/leg/right/right_leg = species_human.get_bodypart(BODY_ZONE_R_LEG)
var/obj/item/bodypart/leg/left/left_leg = species_human.get_bodypart(BODY_ZONE_L_LEG)
var/datum/sprite_accessory/markings = GLOB.moth_markings_list[species_human.dna.features["moth_markings"]]
if(!HAS_TRAIT(species_human, TRAIT_HUSK))
// organic body markings (oh my god this is terrible please rework this to be done on the limbs themselves i beg you)
if(HAS_MARKINGS in species_traits)
var/obj/item/bodypart/chest/chest = species_human.get_bodypart(BODY_ZONE_CHEST)
var/obj/item/bodypart/arm/right/right_arm = species_human.get_bodypart(BODY_ZONE_R_ARM)
var/obj/item/bodypart/arm/left/left_arm = species_human.get_bodypart(BODY_ZONE_L_ARM)
var/obj/item/bodypart/leg/right/right_leg = species_human.get_bodypart(BODY_ZONE_R_LEG)
var/obj/item/bodypart/leg/left/left_leg = species_human.get_bodypart(BODY_ZONE_L_LEG)
var/datum/sprite_accessory/markings = GLOB.moth_markings_list[species_human.dna.features["moth_markings"]]
if(noggin && (IS_ORGANIC_LIMB(noggin)))
var/mutable_appearance/markings_head_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_head", -BODY_LAYER)
markings_head_overlay.pixel_y += height_offset
@@ -789,21 +760,21 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(!(HAS_TRAIT(source, TRAIT_HUSK)))
if(!forced_colour)
switch(accessory.color_src)
if(MUTCOLORS)
if(MUTANT_COLOR)
if(fixed_mut_color)
accessory_overlay.color = fixed_mut_color
else
accessory_overlay.color = source.dna.features["mcolor"]
if(HAIR)
if(HAIR_COLOR)
if(hair_color == "mutcolor")
accessory_overlay.color = source.dna.features["mcolor"]
else if(hair_color == "fixedmutcolor")
accessory_overlay.color = fixed_mut_color
else
accessory_overlay.color = source.hair_color
if(FACEHAIR)
if(FACIAL_HAIR_COLOR)
accessory_overlay.color = source.facial_hair_color
if(EYECOLOR)
if(EYE_COLOR)
accessory_overlay.color = source.eye_color_left
else
accessory_overlay.color = forced_colour
@@ -1098,7 +1069,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
source.domutcheck()
if(time_since_irradiated > RAD_MOB_HAIRLOSS && SPT_PROB(RAD_MOB_HAIRLOSS_PROB, seconds_per_tick))
if(!(source.hairstyle == "Bald") && (HAIR in species_traits))
var/obj/item/bodypart/head/head = source.get_bodypart(BODY_ZONE_HEAD)
if(!(source.hairstyle == "Bald") && (head?.head_flags & HEAD_HAIR|HEAD_FACIAL_HAIR))
to_chat(source, span_danger("Your hair starts to fall out in clumps..."))
addtimer(CALLBACK(src, PROC_REF(go_bald), source), 5 SECONDS)
@@ -1814,7 +1786,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
if ( \
(preference.relevant_mutant_bodypart in mutant_bodyparts) \
|| (preference.relevant_species_trait in species_traits) \
|| (preference.relevant_external_organ in external_organs)
|| (preference.relevant_external_organ in external_organs) \
|| (preference.relevant_head_flag && check_head_flags(preference.relevant_head_flag)) \
)
features += preference.savefile_key
@@ -2331,3 +2304,13 @@ GLOBAL_LIST_EMPTY(features_by_species)
/// Creates body parts for the target completely from scratch based on the species
/datum/species/proc/create_fresh_body(mob/living/carbon/target)
target.create_bodyparts(bodypart_overrides)
/**
* Checks if the species has a head with these head flags, by default.
* Admittedly, this is a very weird and seemingly redundant proc, but it
* gets used by some preferences (such as hair style) to determine whether
* or not they are accessible.
**/
/datum/species/proc/check_head_flags(check_flags = NONE)
var/obj/item/bodypart/head/fake_head = bodypart_overrides[BODY_ZONE_HEAD]
return (initial(fake_head.head_flags) & check_flags)
@@ -759,31 +759,12 @@ generate/load female uniform sprites matching all previously decided variables
var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD)
if (!istype(my_head))
if(!istype(my_head))
return
my_head.update_limb(is_creating = update_limb_data)
add_overlay(my_head.get_limb_icon())
update_damage_overlays()
if(my_head && !(HAS_TRAIT(src, TRAIT_HUSK)))
// lipstick
if(lip_style && (LIPS in dna.species.species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/species/human/human_face.dmi', "lips_[lip_style]", -BODY_LAYER)
lip_overlay.color = lip_color
my_head.worn_face_offset?.apply_offset(lip_overlay)
add_overlay(lip_overlay)
// eyes
if(!(NOEYESPRITES in dna.species.species_traits))
var/obj/item/organ/internal/eyes/parent_eyes = get_organ_slot(ORGAN_SLOT_EYES)
if(parent_eyes)
add_overlay(parent_eyes.generate_body_overlay(src))
else
var/mutable_appearance/missing_eyes = mutable_appearance('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER)
my_head.worn_face_offset?.apply_offset(missing_eyes)
add_overlay(missing_eyes)
update_worn_head()
update_worn_mask()
@@ -3,7 +3,6 @@
id = SPECIES_ABDUCTOR
sexes = FALSE
species_traits = list(
NOEYESPRITES,
NO_UNDERWEAR,
)
inherent_traits = list(
@@ -11,7 +10,6 @@
TRAIT_NOHUNGER,
TRAIT_VIRUSIMMUNE,
TRAIT_NOBLOOD,
TRAIT_NO_DEBRAIN_OVERLAY,
TRAIT_CHUNKYFINGERS_IGNORE_BATON,
)
mutanttongue = /obj/item/organ/internal/tongue/abductor
@@ -23,7 +23,6 @@
TRAIT_RESISTHIGHPRESSURE,
TRAIT_TOXIMMUNE,
TRAIT_NOBLOOD,
TRAIT_NO_DEBRAIN_OVERLAY,
)
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
@@ -1,12 +1,7 @@
/datum/species/dullahan
name = "Dullahan"
id = SPECIES_DULLAHAN
species_traits = list(
EYECOLOR,
HAIR,
FACEHAIR,
LIPS,
)
species_traits = list()
inherent_traits = list(
TRAIT_NOBREATH,
TRAIT_NOHUNGER,
@@ -14,8 +14,6 @@
DYNCOLORS,
AGENDER,
NO_UNDERWEAR,
HAIR,
FACEHAIR,
)
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
species_cookie = /obj/item/food/energybar
@@ -29,6 +27,7 @@
bodytemp_cold_damage_limit = (T20C - 10) // about 10c
hair_color = "fixedmutcolor"
hair_alpha = 140
facial_hair_alpha = 140
bodypart_overrides = list(
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/ethereal,
@@ -6,7 +6,6 @@
NO_DNA_COPY,
NOTRANSSTING,
NO_UNDERWEAR,
NOEYEHOLES,
NOAUGMENTS,
)
inherent_traits = list(
@@ -1,12 +1,7 @@
/datum/species/human
name = "\improper Human"
id = SPECIES_HUMAN
species_traits = list(
EYECOLOR,
HAIR,
FACEHAIR,
LIPS,
)
species_traits = list()
inherent_traits = list(
TRAIT_CAN_USE_FLIGHT_POTION,
)
@@ -12,7 +12,6 @@
id = SPECIES_JELLYPERSON
species_traits = list(
MUTCOLORS,
EYECOLOR,
)
inherent_traits = list(
TRAIT_TOXINLOVER,
@@ -176,9 +175,12 @@
name = "\improper Slimeperson"
plural_form = "Slimepeople"
id = SPECIES_SLIMEPERSON
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
species_traits = list(
MUTCOLORS,
)
hair_color = "mutcolor"
hair_alpha = 150
facial_hair_alpha = 150
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
mutanteyes = /obj/item/organ/internal/eyes
var/datum/action/innate/split_body/slime_split
@@ -5,8 +5,6 @@
id = SPECIES_LIZARD
species_traits = list(
MUTCOLORS,
EYECOLOR,
LIPS,
)
inherent_traits = list(
TRAIT_CAN_USE_FLIGHT_POTION,
@@ -142,8 +140,6 @@ Lizard subspecies: ASHWALKERS
mutantbrain = /obj/item/organ/internal/brain/primitive
species_traits = list(
MUTCOLORS,
EYECOLOR,
LIPS,
)
inherent_traits = list(
//TRAIT_LITERATE,
@@ -14,15 +14,12 @@
knife_butcher_results = list(/obj/item/food/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
species_traits = list(
NO_UNDERWEAR,
LIPS,
NOEYESPRITES,
NOBLOODOVERLAY,
NOTRANSSTING,
NOAUGMENTS,
)
inherent_traits = list(
TRAIT_GUN_NATURAL,
//TRAIT_LITERATE,
TRAIT_VENTCRAWLER_NUDE,
TRAIT_WEAK_SOUL,
)
@@ -3,7 +3,6 @@
plural_form = "Mothmen"
id = SPECIES_MOTH
species_traits = list(
LIPS,
HAS_MARKINGS,
)
inherent_traits = list(
@@ -10,7 +10,6 @@
species_traits = list(
MUTCOLORS,
NOEYESPRITES,
NO_UNDERWEAR,
)
inherent_traits = list(
@@ -28,7 +27,6 @@
mutanteyes = /obj/item/organ/internal/eyes/night_vision/mushroom
mutantlungs = null
use_skintones = FALSE
var/datum/martial_art/mushpunch/mush
species_language_holder = /datum/language_holder/mushroom
bodypart_overrides = list(
@@ -39,6 +37,7 @@
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mushroom,
BODY_ZONE_CHEST = /obj/item/bodypart/chest/mushroom,
)
var/datum/martial_art/mushpunch/mush
/datum/species/mush/check_roundstart_eligible()
return FALSE //hard locked out of roundstart on the order of design lead kor, this can be removed in the future when planetstation is here OR SOMETHING but right now we have a problem with races.
@@ -14,7 +14,6 @@
TRAIT_RADIMMUNE,
TRAIT_RESISTCOLD,
TRAIT_NOBLOOD,
TRAIT_NO_DEBRAIN_OVERLAY,
)
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
@@ -5,7 +5,6 @@
id = SPECIES_PODPERSON
species_traits = list(
MUTCOLORS,
EYECOLOR,
)
inherent_traits = list(
TRAIT_PLANT_SAFE,
@@ -5,9 +5,7 @@
id = SPECIES_SHADOW
sexes = 0
meat = /obj/item/food/meat/slab/human/mutant/shadow
species_traits = list(
NOEYESPRITES,
)
species_traits = list()
inherent_traits = list(
TRAIT_NOBREATH,
TRAIT_RADIMMUNE,
@@ -6,7 +6,6 @@
meat = /obj/item/food/meat/slab/human/mutant/skeleton
species_traits = list(
NOTRANSSTING,
NOEYESPRITES,
NO_DNA_COPY,
NO_UNDERWEAR,
)
@@ -28,7 +27,6 @@
TRAIT_TOXIMMUNE,
TRAIT_XENO_IMMUNE,
TRAIT_NOBLOOD,
TRAIT_NO_DEBRAIN_OVERLAY,
)
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
mutanttongue = /obj/item/organ/internal/tongue/bone
@@ -8,10 +8,6 @@
name = "Vampire"
id = SPECIES_VAMPIRE
species_traits = list(
EYECOLOR,
HAIR,
FACEHAIR,
LIPS,
DRINKSBLOOD,
BLOOD_CLANS,
)
@@ -550,8 +550,9 @@
affected_human.facial_hairstyle = "Shaved"
affected_human.facial_hair_color = "#000000"
affected_human.hair_color = "#000000"
if(!(HAIR in affected_human.dna.species.species_traits)) //No hair? No problem!
affected_human.dna.species.species_traits += HAIR
var/obj/item/bodypart/head/head = affected_human.get_bodypart(BODY_ZONE_HEAD)
if(head)
head.head_flags |= HEAD_HAIR //No hair? No problem!
if(affected_human.dna.species.use_skintones)
affected_human.skin_tone = "orange"
else if(MUTCOLORS in affected_human.dna.species.species_traits) //Aliens with custom colors simply get turned orange
@@ -2114,12 +2115,10 @@
var/mob/living/carbon/human/human_mob = affected_mob
if(creation_purity == 1 && human_mob.has_quirk(/datum/quirk/item_quirk/bald))
human_mob.remove_quirk(/datum/quirk/item_quirk/bald)
var/datum/species/species_datum = human_mob.dna?.species
if(!species_datum)
var/obj/item/bodypart/head/head = human_mob.get_bodypart(BODY_ZONE_HEAD)
if(!head || (head.head_flags & HEAD_HAIR))
return
if(species_datum.species_traits.Find(HAIR))
return
species_datum.species_traits |= HAIR
head.head_flags |= HEAD_HAIR
var/message
if(HAS_TRAIT(affected_mob, TRAIT_BALD))
message = span_warning("You feel your scalp mutate, but you are still hopelessly bald.")
+1 -13
View File
@@ -36,28 +36,16 @@
is_dimorphic = FALSE
should_draw_greyscale = FALSE
bodypart_traits = list(TRAIT_DISFIGURED, TRAIT_BALD, TRAIT_SHAVED)
head_flags = HEAD_LIPS|HEAD_EYEHOLES|HEAD_DEBRAIN
/obj/item/bodypart/head/psyker/try_attach_limb(mob/living/carbon/new_head_owner, special, abort)
. = ..()
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()
+8 -3
View File
@@ -110,6 +110,10 @@
var/px_x = 0
var/px_y = 0
/**
* A copy of the original owner's species datum species_traits list (very hacky)
* It sucks that we have to do this, but due to MUTCOLORS and others, we have to. For now.
*/
var/species_flags_list = list()
///the type of damage overlay (if any) to use when this bodypart is bruised/burned.
var/dmg_overlay_type = "human"
@@ -791,7 +795,7 @@
// No, xenos don't actually use bodyparts. Don't ask.
var/mob/living/carbon/human/human_owner = owner
var/datum/species/owner_species = human_owner.dna.species
species_flags_list = owner_species.species_traits
species_flags_list = owner_species.species_traits.Copy()
limb_gender = (human_owner.physique == MALE) ? "m" : "f"
if(owner_species.use_skintones)
@@ -911,8 +915,9 @@
. += aux_em_block
//EMISSIVE CODE END
//Ok so legs are a bit goofy in regards to layering, and we will need two images instead of one to fix that
if((body_zone == BODY_ZONE_R_LEG) || (body_zone == BODY_ZONE_L_LEG))
//No need to handle leg layering if dropped, we only face south anyways
if(!dropped && ((body_zone == BODY_ZONE_R_LEG) || (body_zone == BODY_ZONE_L_LEG)))
//Legs are a bit goofy in regards to layering, and we will need two images instead of one to fix that
var/obj/item/bodypart/leg/leg_source = src
for(var/image/limb_image in .)
//remove the old, unmasked image
@@ -91,7 +91,7 @@
SEND_SIGNAL(owner, COMSIG_CARBON_REMOVE_LIMB, src, dismembered)
SEND_SIGNAL(src, COMSIG_BODYPART_REMOVED, owner, dismembered)
update_limb(TRUE)
update_limb(dropping_limb = TRUE)
//limb is out and about, it can't really be considered an implant
bodypart_flags &= ~BODYPART_IMPLANTED
owner.remove_bodypart(src)
@@ -372,7 +372,7 @@
SEND_SIGNAL(new_limb_owner, COMSIG_CARBON_POST_ATTACH_LIMB, src, special)
return TRUE
/obj/item/bodypart/head/try_attach_limb(mob/living/carbon/new_head_owner, special = FALSE, abort = FALSE)
/obj/item/bodypart/head/try_attach_limb(mob/living/carbon/new_head_owner, special = FALSE)
// These are stored before calling super. This is so that if the head is from a different body, it persists its appearance.
var/real_name = src.real_name
@@ -415,6 +415,8 @@
sexy_chad.grad_color[GRADIENT_HAIR_KEY] = hair_gradient_color
sexy_chad.grad_style[GRADIENT_FACIAL_HAIR_KEY] = facial_hair_gradient_style
sexy_chad.grad_color[GRADIENT_FACIAL_HAIR_KEY] = facial_hair_gradient_color
sexy_chad.lip_style = lip_style
sexy_chad.lip_color = lip_color
new_head_owner.updatehealth()
new_head_owner.update_body()
+106 -66
View File
@@ -36,36 +36,55 @@
var/show_organs_on_examine = TRUE
//Limb appearance info:
var/real_name = "" //Replacement name
///Hair color source
/// Replacement name
var/real_name = ""
/// Flags related to appearance, such as hair, lips, etc
var/head_flags = HEAD_ALL_FEATURES
/// Hair style
var/hair_style = "Bald"
/// Hair color source
var/hair_color_source = null
///Hair colour and style
/// Hair colour and style
var/hair_color = "#000000"
///An override color that can be cleared later.
/// Hair alpha
var/hair_alpha = 255
/// Hair gradient style, if any
var/hair_gradient_style = null
/// Hair gradient color, if any
var/hair_gradient_color = null
/// Is the hair currently hidden by something?
var/hair_hidden = FALSE
///Facial hair style
var/facial_hairstyle = "Shaved"
///Facial hair color
var/facial_hair_color = "#000000"
///Facial hair alpha
var/facial_hair_alpha = 255
///Facial hair gradient style, if any
var/facial_hair_gradient_style = null
///Facial hair gradient color, if any
var/facial_hair_gradient_color = null
///Is the facial hair currently hidden by something?
var/facial_hair_hidden = FALSE
/// An override color that can be cleared later, affects both hair and facial hair
var/override_hair_color = null
///An override that cannot be cleared under any circumstances
/// An override that cannot be cleared under any circumstances, affects both hair and facial hair
var/fixed_hair_color = null
var/hair_style = "Bald"
var/hair_alpha = 255
var/hair_gradient_style = null
var/hair_gradient_color = null
//Facial hair colour and style
var/facial_hair_color = "#000000"
var/facial_hairstyle = "Shaved"
var/facial_hair_gradient_style = null
var/facial_hair_gradient_color = null
///Is the hair currently hidden by something?
var/hair_hidden
///Is the facial hair currently hidden by something?
var/facial_hair_hidden
///Type of lipstick being used, basically
var/lip_style
///Lipstick color
var/lip_color = "white"
///Current lipstick trait, if any (such as TRAIT_KISS_OF_DEATH)
var/stored_lipstick_trait
///Draw this head as "debrained"
VAR_PROTECTED/show_debrained = FALSE
var/lip_style
var/lip_color = "white"
///Draw this head as missing eyes
VAR_PROTECTED/show_missing_eyes = FALSE
/// Offset to apply to equipment worn on the ears
var/datum/worn_feature_offset/worn_ears_offset
@@ -78,7 +97,8 @@
/// Offset to apply to overlays placed on the face
var/datum/worn_feature_offset/worn_face_offset
var/stored_lipstick_trait
///The image for lipstick
var/mutable_appearance/lip_overlay
///The image for hair
var/mutable_appearance/hair_overlay
///The image for hair gradient
@@ -196,75 +216,96 @@
facial_hairstyle = "Shaved"
lip_style = null
stored_lipstick_trait = null
update_hair_and_lips()
update_hair_and_lips(dropping_limb, is_creating)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/obj/item/bodypart/head/get_limb_icon(dropped, draw_external_organs)
cut_overlays()
. = ..()
if(dropped) //certain overlays only appear when the limb is being detached from its owner.
if(IS_ORGANIC_LIMB(src)) //having a robotic head hides certain features.
//facial hair
if(facial_hairstyle && (FACEHAIR in species_flags_list))
var/datum/sprite_accessory/sprite = GLOB.facial_hairstyles_list[facial_hairstyle]
if(sprite)
var/image/facial_overlay = image(sprite.icon, "[sprite.icon_state]", -HAIR_LAYER, SOUTH)
facial_overlay.color = facial_hair_color
facial_overlay.alpha = hair_alpha
. += facial_overlay
if(!eyes && !(NOEYEHOLES in species_flags_list) && !(NOEYESPRITES in species_flags_list))
var/image/no_eyes = image('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER, SOUTH)
worn_glasses_offset?.apply_offset(no_eyes)
. += no_eyes
//Applies the debrained overlay if there is no brain
if(!brain)
. += get_debrain_overlay(can_rotate = FALSE)
else
var/datum/sprite_accessory/sprite2 = GLOB.hairstyles_list[hair_style]
if(sprite2 && (HAIR in species_flags_list))
var/image/hair_overlay = image(sprite2.icon, "[sprite2.icon_state]", -HAIR_LAYER, SOUTH)
hair_overlay.color = hair_color
hair_overlay.alpha = hair_alpha
. += hair_overlay
// logic for the overlays changes when dropped (ugh, rework this later if possible)
if(dropped)
//BAHHHH don't do any of this if we are husked
if(is_husked)
return .
// lipstick
if(lip_style)
if(lip_style && (head_flags & HEAD_LIPS))
var/image/lips_overlay = image('icons/mob/species/human/human_face.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH)
lips_overlay.color = lip_color
worn_face_offset?.apply_offset(lips_overlay)
. += lips_overlay
//facial hair
if(facial_hairstyle && (head_flags & HEAD_FACIAL_HAIR))
var/datum/sprite_accessory/facial_hair_sprite = GLOB.facial_hairstyles_list[facial_hairstyle]
if(facial_hair_sprite)
var/image/facial_overlay = image(facial_hair_sprite.icon, "[facial_hair_sprite.icon_state]", -HAIR_LAYER, SOUTH)
facial_overlay.color = facial_hair_color
facial_overlay.alpha = hair_alpha
. += facial_overlay
//Applies the debrained overlay if there is no brain
if(!brain && (head_flags & HEAD_DEBRAIN))
. += get_debrain_overlay(can_rotate = FALSE)
//Otherwise, applies hair
else if(hair_style && (head_flags & HEAD_HAIR))
var/datum/sprite_accessory/hair_sprite = GLOB.hairstyles_list[hair_style]
if(hair_sprite && (head_flags & HEAD_HAIR))
var/image/hair_overlay = image(hair_sprite.icon, "[hair_sprite.icon_state]", -HAIR_LAYER, SOUTH)
hair_overlay.color = hair_color
hair_overlay.alpha = hair_alpha
. += hair_overlay
// eyes
if(eyes && eyes.eye_icon_state && !(NOEYESPRITES in species_flags_list)) // This is a bit of copy/paste code from eyes.dm:generate_body_overlay
// This is a bit of copy/paste code from eyes.dm:generate_body_overlay
if(eyes?.eye_icon_state && (head_flags & HEAD_EYESPRITES))
var/image/eye_left = image('icons/mob/species/human/human_face.dmi', "[eyes.eye_icon_state]_l", -BODY_LAYER, SOUTH)
var/image/eye_right = image('icons/mob/species/human/human_face.dmi', "[eyes.eye_icon_state]_r", -BODY_LAYER, SOUTH)
if(eyes.eye_color_left)
eye_left.color = eyes.eye_color_left
if(eyes.eye_color_right)
eye_right.color = eyes.eye_color_right
if(head_flags & HEAD_EYECOLOR)
if(eyes.eye_color_left)
eye_left.color = eyes.eye_color_left
if(eyes.eye_color_right)
eye_right.color = eyes.eye_color_right
if(eyes.overlay_ignore_lighting)
eye_left.overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, src, alpha = eye_left.alpha)
eye_right.overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, src, alpha = eye_right.alpha)
if(worn_face_offset)
worn_face_offset.apply_offset(eye_left)
worn_face_offset.apply_offset(eye_right)
. += eye_left
. += eye_right
else if(!eyes && (head_flags & HEAD_EYEHOLES))
var/image/no_eyes = image('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER, SOUTH)
worn_face_offset?.apply_offset(no_eyes)
. += no_eyes
else
if(!facial_hair_hidden && facial_overlay && (FACEHAIR in species_flags_list))
if(lip_overlay && (head_flags & HEAD_LIPS))
worn_face_offset?.apply_offset(lip_overlay)
. += lip_overlay
if(!facial_hair_hidden && facial_overlay && (head_flags & HEAD_FACIAL_HAIR))
facial_overlay.alpha = hair_alpha
. += facial_overlay
if(facial_gradient_overlay)
. += facial_gradient_overlay
if(show_debrained)
if(show_debrained && (head_flags & HEAD_DEBRAIN))
. += get_debrain_overlay(can_rotate = TRUE)
else if(!hair_hidden && hair_overlay && (HAIR in species_flags_list))
else if(!hair_hidden && hair_overlay && (head_flags & HEAD_HAIR))
hair_overlay.alpha = hair_alpha
. += hair_overlay
if(hair_gradient_overlay)
. += hair_gradient_overlay
if(show_missing_eyes && (head_flags && HEAD_EYEHOLES))
var/mutable_appearance/no_eyes = mutable_appearance('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER)
worn_face_offset?.apply_offset(no_eyes)
. += no_eyes
return
/// Returns an appropriate debrained icon state
/obj/item/bodypart/head/proc/get_debrain_overlay(can_rotate = TRUE)
var/debrain_icon = 'icons/mob/species/human/human_face.dmi'
@@ -278,11 +319,9 @@
else if(bodytype & BODYTYPE_GOLEM)
debrain_icon = 'icons/mob/species/golems.dmi'
debrain_icon_state = "debrained"
else if((TRAIT_NOBLOOD in species_flags_list))
return null
var/image/debrain_overlay
if (can_rotate)
if(can_rotate)
debrain_overlay = mutable_appearance(debrain_icon, debrain_icon_state, HAIR_LAYER)
else
debrain_overlay = image(debrain_icon, debrain_icon_state, -HAIR_LAYER, SOUTH)
@@ -336,6 +375,7 @@
should_draw_greyscale = FALSE
dmg_overlay_type = SPECIES_MONKEY
is_dimorphic = FALSE
head_flags = HEAD_LIPS|HEAD_DEBRAIN
/obj/item/bodypart/head/alien
icon = 'icons/mob/species/alien/bodyparts.dmi'
@@ -1,65 +1,62 @@
#define SET_OVERLAY_VALUE(X,Y,Z) if(X) X.Y = Z
#define SET_OVERLAY_VALUE(overlay,variable,value) if(overlay) overlay.variable = value
///Part of `update_limb()`, this proc does what the name implies.
/obj/item/bodypart/head/proc/update_hair_and_lips()
/// Part of `update_limb()`, this proc does what the name implies.
/obj/item/bodypart/head/proc/update_hair_and_lips(dropping_limb, is_creating)
// THIS PROC DOES NOT WORK FOR DROPPED HEADS. YET.
if(!owner)
return
var/mob/living/carbon/human/human_head_owner = owner
var/datum/species/owner_species = human_head_owner.dna.species
if(human_head_owner.lip_style && (LIPS in owner_species.species_traits))
lip_style = human_head_owner.lip_style
lip_color = human_head_owner.lip_color
else
lip_style = null
lip_color = "white"
///FACIAL HAIR CHECKS START
//we check if our hat or helmet hides our facial hair.
//HIDDEN CHECKS START
hair_hidden = FALSE
facial_hair_hidden = FALSE
if(human_head_owner.head)
var/obj/item/hat = human_head_owner.head
if(hat.flags_inv & HIDEHAIR)
hair_hidden = TRUE
if(hat.flags_inv & HIDEFACIALHAIR)
facial_hair_hidden = TRUE
if(human_head_owner.wear_mask)
var/obj/item/mask = human_head_owner.wear_mask
if(mask.flags_inv & HIDEHAIR)
hair_hidden = TRUE
if(mask.flags_inv & HIDEFACIALHAIR)
facial_hair_hidden = TRUE
///FACIAL HAIR CHECKS END
///HAIR CHECKS START
hair_hidden = FALSE
if(human_head_owner.head)
var/obj/item/hat = human_head_owner.head
if(hat.flags_inv & HIDEHAIR)
hair_hidden = TRUE
if(human_head_owner.w_uniform)
var/obj/item/item_uniform = human_head_owner.w_uniform
if(item_uniform.flags_inv & HIDEHAIR)
hair_hidden = TRUE
if(human_head_owner.wear_mask)
var/obj/item/mask = human_head_owner.wear_mask
if(mask.flags_inv & HIDEHAIR)
hair_hidden = TRUE
///HAIR CHECKS END
//invisibility stuff
if(HAS_TRAIT(human_head_owner, TRAIT_INVISIBLE_MAN))
if(item_uniform.flags_inv & HIDEFACIALHAIR)
facial_hair_hidden = TRUE
//invisibility and husk stuff
if(HAS_TRAIT(human_head_owner, TRAIT_INVISIBLE_MAN) || HAS_TRAIT(human_head_owner, TRAIT_HUSK))
hair_hidden = TRUE
facial_hair_hidden = TRUE
//HIDDEN CHECKS END
if(!hair_hidden && !owner.get_organ_slot(ORGAN_SLOT_BRAIN) && !HAS_TRAIT(owner, TRAIT_NO_DEBRAIN_OVERLAY))
if(!hair_hidden && !owner.get_organ_slot(ORGAN_SLOT_BRAIN) && (head_flags & HEAD_DEBRAIN) && !HAS_TRAIT(owner, TRAIT_NO_DEBRAIN_OVERLAY))
show_debrained = TRUE
else
show_debrained = FALSE
if(!owner.get_organ_slot(ORGAN_SLOT_EYES) && (head_flags & HEAD_EYEHOLES))
show_missing_eyes = TRUE
else
show_missing_eyes = FALSE
var/datum/sprite_accessory/sprite_accessory
lip_overlay = null
facial_overlay = null
facial_gradient_overlay = null
hair_overlay = null
hair_gradient_overlay = null
lip_style = human_head_owner.lip_style
lip_color = human_head_owner.lip_color
hair_alpha = owner_species.hair_alpha
hair_color = human_head_owner.hair_color
facial_hair_color = human_head_owner.facial_hair_color
@@ -69,31 +66,38 @@
var/atom/location = loc || owner || src
if(facial_hairstyle && !facial_hair_hidden && (FACEHAIR in species_flags_list))
if(!facial_hair_hidden && lip_style && (head_flags & HEAD_LIPS))
lip_overlay = mutable_appearance('icons/mob/species/human/human_face.dmi', "lips_[lip_style]", -BODY_LAYER)
lip_overlay.color = lip_color
if(!facial_hair_hidden && facial_hairstyle && (head_flags & HEAD_FACIAL_HAIR))
sprite_accessory = GLOB.facial_hairstyles_list[facial_hairstyle]
if(sprite_accessory)
//Create the overlay
//Overlay
facial_overlay = mutable_appearance(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER)
facial_overlay.overlays += emissive_blocker(facial_overlay.icon, facial_overlay.icon_state, location, alpha = hair_alpha)
facial_overlay.alpha = facial_hair_alpha
//Gradients
facial_hair_gradient_style = LAZYACCESS(human_head_owner.grad_style, GRADIENT_FACIAL_HAIR_KEY)
if(facial_hair_gradient_style)
facial_hair_gradient_color = LAZYACCESS(human_head_owner.grad_color, GRADIENT_FACIAL_HAIR_KEY)
facial_gradient_overlay = make_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, HAIR_LAYER, GLOB.facial_hair_gradients_list[facial_hair_gradient_style], facial_hair_gradient_color)
//Emissive
facial_overlay.overlays += emissive_blocker(facial_overlay.icon, facial_overlay.icon_state, location, alpha = facial_hair_alpha)
facial_overlay.overlays += emissive_blocker(sprite_accessory.icon, sprite_accessory.icon_state, location, alpha = hair_alpha)
if(!hair_hidden && !show_debrained && (HAIR in species_flags_list))
if(!show_debrained && !hair_hidden && hair_style && (head_flags & HEAD_HAIR))
sprite_accessory = GLOB.hairstyles_list[hair_style]
if(sprite_accessory)
//Overlay
hair_overlay = mutable_appearance(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER)
hair_overlay.overlays += emissive_blocker(hair_overlay.icon, hair_overlay.icon_state, location, alpha = hair_alpha)
hair_overlay.alpha = hair_alpha
//Gradients
hair_gradient_style = LAZYACCESS(human_head_owner.grad_style, GRADIENT_HAIR_KEY)
if(hair_gradient_style)
hair_gradient_color = LAZYACCESS(human_head_owner.grad_color, GRADIENT_HAIR_KEY)
hair_gradient_overlay = make_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, HAIR_LAYER, GLOB.hair_gradients_list[hair_gradient_style], hair_gradient_color)
//Emissive
hair_overlay.overlays += emissive_blocker(hair_overlay.icon, hair_overlay.icon_state, location, alpha = hair_alpha)
//CREATION-ONLY END
//HAIR COLOR START
if(!override_hair_color)
if(hair_color_source)
+1 -1
View File
@@ -166,7 +166,7 @@
if(BODY_ZONE_CHEST)
new_bodypart = new /obj/item/bodypart/chest/alien()
if(new_bodypart)
new_bodypart.update_limb(src)
new_bodypart.update_limb(is_creating = TRUE)
@@ -301,6 +301,8 @@
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
head_flags = HEAD_EYESPRITES
var/obj/item/assembly/flash/handheld/flash1 = null
var/obj/item/assembly/flash/handheld/flash2 = null
@@ -7,6 +7,7 @@
unarmed_attack_sound = 'sound/weapons/etherealhit.ogg'
unarmed_miss_sound = 'sound/weapons/etherealmiss.ogg'
brute_modifier = 1.25 //ethereal are weak to brute damage
head_flags = HEAD_HAIR|HEAD_FACIAL_HAIR|HEAD_EYESPRITES|HEAD_EYEHOLES|HEAD_DEBRAIN
/obj/item/bodypart/head/ethereal/update_limb(dropping_limb, is_creating)
. = ..()
@@ -2,6 +2,7 @@
icon_greyscale = 'icons/mob/species/lizard/bodyparts.dmi'
limb_id = SPECIES_LIZARD
is_dimorphic = FALSE
head_flags = HEAD_LIPS|HEAD_EYESPRITES|HEAD_EYECOLOR|HEAD_EYEHOLES|HEAD_DEBRAIN
/obj/item/bodypart/chest/lizard
icon_greyscale = 'icons/mob/species/lizard/bodyparts.dmi'
@@ -3,6 +3,7 @@
limb_id = SPECIES_SNAIL
is_dimorphic = FALSE
burn_modifier = 2
head_flags = HEAD_EYESPRITES|HEAD_DEBRAIN
/obj/item/bodypart/chest/snail
limb_id = SPECIES_SNAIL
@@ -39,6 +40,7 @@
limb_id = SPECIES_ABDUCTOR
is_dimorphic = FALSE
should_draw_greyscale = FALSE
head_flags = NONE
/obj/item/bodypart/chest/abductor
biological_state = BIO_INORGANIC
@@ -75,6 +77,7 @@
is_dimorphic = TRUE
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/jelly
biological_state = BIO_INORGANIC
@@ -112,6 +115,7 @@
biological_state = BIO_INORGANIC
limb_id = SPECIES_SLIMEPERSON
is_dimorphic = FALSE
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/slime
biological_state = BIO_INORGANIC
@@ -139,6 +143,7 @@
biological_state = BIO_INORGANIC
limb_id = SPECIES_LUMINESCENT
is_dimorphic = TRUE
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/luminescent
biological_state = BIO_INORGANIC
@@ -166,6 +171,7 @@
limb_id = SPECIES_ZOMBIE
is_dimorphic = FALSE
should_draw_greyscale = FALSE
head_flags = HEAD_EYESPRITES|HEAD_DEBRAIN
/obj/item/bodypart/chest/zombie
limb_id = SPECIES_ZOMBIE
@@ -193,6 +199,7 @@
limb_id = SPECIES_PODPERSON
is_dimorphic = TRUE
burn_modifier = 1.25
head_flags = HEAD_EYESPRITES|HEAD_EYECOLOR|HEAD_EYEHOLES|HEAD_DEBRAIN
/obj/item/bodypart/chest/pod
limb_id = SPECIES_PODPERSON
@@ -228,6 +235,7 @@
limb_id = SPECIES_FLYPERSON
is_dimorphic = FALSE
should_draw_greyscale = FALSE
head_flags = HEAD_EYESPRITES|HEAD_EYEHOLES|HEAD_DEBRAIN
/obj/item/bodypart/chest/fly
limb_id = SPECIES_FLYPERSON
@@ -257,6 +265,7 @@
is_dimorphic = FALSE
should_draw_greyscale = FALSE
burn_modifier = 1.5
head_flags = NONE
/obj/item/bodypart/chest/shadow
biological_state = BIO_INORGANIC
@@ -302,6 +311,7 @@
is_dimorphic = FALSE
should_draw_greyscale = FALSE
dmg_overlay_type = null
head_flags = NONE
/obj/item/bodypart/chest/skeleton
biological_state = BIO_BONE
@@ -339,6 +349,7 @@
limb_id = SPECIES_MUSHROOM
is_dimorphic = TRUE
burn_modifier = 1.25
head_flags = NONE
/obj/item/bodypart/chest/mushroom
limb_id = SPECIES_MUSHROOM
@@ -385,6 +396,7 @@
is_dimorphic = FALSE
should_draw_greyscale = FALSE
dmg_overlay_type = null
head_flags = NONE
/obj/item/bodypart/head/golem/Initialize(mapload)
worn_ears_offset = new(
@@ -5,6 +5,7 @@
limb_id = SPECIES_MOTH
is_dimorphic = FALSE
should_draw_greyscale = FALSE
head_flags = HEAD_LIPS|HEAD_EYESPRITES|HEAD_EYEHOLES|HEAD_DEBRAIN //what the fuck, moths have lips?
/obj/item/bodypart/chest/moth
icon = 'icons/mob/species/moth/bodyparts.dmi'
@@ -9,6 +9,7 @@
dmg_overlay_type = null
brute_modifier = 1.5 //Plasmemes are weak
burn_modifier = 1.5 //Plasmemes are weak
head_flags = HEAD_EYESPRITES
/obj/item/bodypart/chest/plasmaman
icon = 'icons/mob/species/plasmaman/bodyparts.dmi'
+11 -12
View File
@@ -56,7 +56,7 @@
return
eye_recipient.cure_blind(NO_EYES)
apply_damaged_eye_effects()
refresh(eye_recipient, inserting = TRUE)
refresh(eye_recipient, inserting = TRUE, call_update = TRUE)
/// Refreshes the visuals of the eyes
/// If call_update is TRUE, we also will call update_body
@@ -85,7 +85,7 @@
affected_human.add_fov_trait(type, native_fov)
if(call_update)
affected_human.dna?.species?.handle_body(affected_human) //updates eye icon
affected_human.update_body()
/obj/item/organ/internal/eyes/Remove(mob/living/carbon/eye_owner, special = FALSE)
. = ..()
@@ -95,9 +95,9 @@
human_owner.eye_color_left = old_eye_color_left
if(initial(eye_color_right))
human_owner.eye_color_right = old_eye_color_right
human_owner.update_body()
if(native_fov)
eye_owner.remove_fov_trait(type)
human_owner.update_body()
// Cure blindness from eye damage
eye_owner.cure_blind(EYE_DAMAGE)
@@ -125,11 +125,6 @@
var/mutable_appearance/eye_left = mutable_appearance('icons/mob/species/human/human_face.dmi', "[eye_icon_state]_l", -BODY_LAYER)
var/mutable_appearance/eye_right = mutable_appearance('icons/mob/species/human/human_face.dmi', "[eye_icon_state]_r", -BODY_LAYER)
var/list/overlays = list(eye_left, eye_right)
if(EYECOLOR in parent.dna?.species.species_traits)
eye_right.color = eye_color_right
eye_left.color = eye_color_left
var/obscured = parent.check_obscured_slots(TRUE)
if(overlay_ignore_lighting && !(obscured & ITEM_SLOT_EYES))
@@ -137,11 +132,15 @@
eye_right.overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, parent, alpha = eye_right.alpha)
var/obj/item/bodypart/head/my_head = parent.get_bodypart(BODY_ZONE_HEAD)
if(my_head?.worn_face_offset)
for(var/mutable_appearance/overlay in overlays)
my_head.worn_face_offset.apply_offset(overlay)
if(my_head)
if(my_head.head_flags & HEAD_EYECOLOR)
eye_right.color = eye_color_right
eye_left.color = eye_color_left
if(my_head.worn_face_offset)
my_head.worn_face_offset.apply_offset(eye_left)
my_head.worn_face_offset.apply_offset(eye_right)
return overlays
return list(eye_left, eye_right)
#undef OFFSET_X
#undef OFFSET_Y
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB