diff --git a/code/__defines/bodytype.dm b/code/__defines/bodytype.dm index cd09f120864..0fefad2a52b 100644 --- a/code/__defines/bodytype.dm +++ b/code/__defines/bodytype.dm @@ -9,10 +9,8 @@ // Bodytype appearance flags #define HAS_SKIN_TONE_NORMAL BITFLAG(0) // Skin tone selectable in chargen for baseline humans (0-220) #define HAS_SKIN_COLOR BITFLAG(1) // Skin colour selectable in chargen. (RGB) -#define HAS_LIPS BITFLAG(2) // Lips are drawn onto the mob icon. (lipstick) #define HAS_UNDERWEAR BITFLAG(3) // Underwear is drawn onto the mob icon. #define HAS_EYE_COLOR BITFLAG(4) // Eye colour selectable in chargen. (RGB) -#define HAS_HAIR_COLOR BITFLAG(5) // Hair colour selectable in chargen. (RGB) #define RADIATION_GLOWS BITFLAG(6) // Radiation causes this character to glow. #define HAS_SKIN_TONE_GRAV BITFLAG(7) // Skin tone selectable in chargen for grav-adapted humans (0-100) #define HAS_SKIN_TONE_SPCR BITFLAG(8) // Skin tone selectable in chargen for spacer humans (0-165) diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 3c168317126..abadda59545 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -385,3 +385,21 @@ var/global/list/dexterity_levels = list( // Enum for type of consumption, largely just cosmetic currently. #define EATING_METHOD_EAT 0 #define EATING_METHOD_DRINK 1 + +#define SAC_HAIR /decl/sprite_accessory_category/hair +#define SAC_FACIAL_HAIR /decl/sprite_accessory_category/facial_hair +#define SAC_COSMETICS /decl/sprite_accessory_category/cosmetics +#define SAC_MARKINGS /decl/sprite_accessory_category/markings +#define SAC_HORNS /decl/sprite_accessory_category/horns +#define SAC_FRILLS /decl/sprite_accessory_category/frills + +// Helpers for setting mob appearance. They are extremely ugly, hence the helpers. +#define SET_HAIR_STYLE(TARGET, STYLE, SKIP_UPDATE) (TARGET.set_organ_sprite_accessory_by_category((STYLE), SAC_HAIR, null, TRUE, FALSE, BP_HEAD, SKIP_UPDATE)) +#define GET_HAIR_STYLE(TARGET) (TARGET.get_organ_sprite_accessory_by_category(SAC_HAIR, BP_HEAD)) +#define SET_HAIR_COLOUR(TARGET, COLOUR, SKIP_UPDATE) (TARGET.set_organ_sprite_accessory_by_category(null, SAC_HAIR, (COLOUR), FALSE, TRUE, BP_HEAD, SKIP_UPDATE)) +#define GET_HAIR_COLOUR(TARGET) (TARGET.get_organ_sprite_accessory(GET_HAIR_STYLE(TARGET), BP_HEAD)) + +#define SET_FACIAL_HAIR_STYLE(TARGET, STYLE, SKIP_UPDATE) (TARGET.set_organ_sprite_accessory_by_category((STYLE), SAC_FACIAL_HAIR, null, TRUE, FALSE, BP_HEAD, SKIP_UPDATE)) +#define GET_FACIAL_HAIR_STYLE(TARGET) (TARGET.get_organ_sprite_accessory_by_category(SAC_FACIAL_HAIR, BP_HEAD)) +#define SET_FACIAL_HAIR_COLOUR(TARGET, COLOUR, SKIP_UPDATE) (TARGET.set_organ_sprite_accessory_by_category(null, SAC_FACIAL_HAIR, (COLOUR), FALSE, TRUE, BP_HEAD, SKIP_UPDATE)) +#define GET_FACIAL_HAIR_COLOUR(TARGET) (TARGET.get_organ_sprite_accessory(GET_FACIAL_HAIR_STYLE(TARGET), BP_HEAD)) diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm index 75f6b2f4433..6eb89ecd9fb 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/lists.dm @@ -284,19 +284,20 @@ Checks if a list has the same entries and values as an element of big. //Returns the next element in parameter list after first appearance of parameter element. If it is the last element of the list or not present in list, returns first element. /proc/next_in_list(element, list/L) - for(var/i=1, i= L.len) + return L[1] return L[i+1] return L[1] //Returns the previous element in parameter list after first appearance of parameter element. If it is the first element of the list or not present in list, returns first element. /proc/previous_in_list(element, list/L) - for(var/i=1, i 0 && hair <= length(hair_subtypes)) - set_hairstyle(hair_subtypes[hair], skip_update = TRUE) - update_hair = TRUE - - //Facial Hair - var/list/beard_subtypes = decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/facial_hair) - var/beard = dna.GetUIValueRange(DNA_UI_BEARD_STYLE, length(beard_subtypes)) - if((0 < beard) && (beard <= length(beard_subtypes))) - set_facial_hairstyle(beard_subtypes[beard], skip_update = TRUE) - update_hair = TRUE - force_update_limbs() - if(update_hair) - update_hair(update_icons = FALSE) + update_hair(update_icons = FALSE) update_eyes() return TRUE diff --git a/code/game/machinery/vending/misc.dm b/code/game/machinery/vending/misc.dm index ad2fff89394..0dc1723ea84 100644 --- a/code/game/machinery/vending/misc.dm +++ b/code/game/machinery/vending/misc.dm @@ -62,8 +62,7 @@ /obj/item/haircomb = 8, /obj/item/clothing/glasses/eyepatch/monocle = 5, /obj/item/clothing/glasses/sunglasses = 5, - /obj/item/lipstick = 3, - /obj/random/lipstick = 3, + /obj/random/makeup = 3, /obj/item/storage/wallet/poly = 2 ) contraband = list( diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 1cd5744c816..c7a9b2d24f8 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -1,45 +1,51 @@ -/obj/item/lipstick //this is the base type and its red +/obj/item/cosmetics gender = PLURAL - name = "ruby lipstick" - desc = "An unbranded tube of lipstick." - icon = 'icons/obj/items/lipstick.dmi' - icon_state = "lipstick_0" + name = "abstract makeup" + desc = "An unbranded tube of makeup." obj_flags = OBJ_FLAG_HOLLOW w_class = ITEM_SIZE_TINY slot_flags = SLOT_EARS - color = "#e00606" + color = COLOR_SILVER material = /decl/material/solid/organic/plastic - var/color_desc = "ruby" + abstract_type = /obj/item/cosmetics + + var/base_icon_state + var/apply_marking_to_limb = BP_HEAD + var/apply_to_zone = BP_MOUTH + var/cosmetic_type + var/makeup_color + var/color_desc var/open = FALSE -/obj/item/lipstick/Initialize() +/obj/item/cosmetics/Initialize() . = ..() + if(!cosmetic_type) + PRINT_STACK_TRACE("Cosmetic item initialized with no cosmetic_type set!") + return INITIALIZE_HINT_QDEL if(color_desc) + name = "[color_desc] [name]" desc += " This one is in [color_desc]." update_icon() //'lipstick' and 'key' are both coloured by var color -/obj/item/lipstick/on_update_icon() +/obj/item/cosmetics/on_update_icon() . = ..() if(open) - icon_state = "the_stick" + icon_state = "[base_icon_state]_open" + add_overlay(overlay_image(icon, "[base_icon_state]_extended", makeup_color, RESET_COLOR)) else - icon_state = "" - - add_overlay(list( - overlay_image(icon, "lipstick_[open]", flags=RESET_COLOR), - overlay_image(icon, "key") - )) + icon_state = "[base_icon_state]_closed" + add_overlay(overlay_image(icon, "[base_icon_state]_key", makeup_color, RESET_COLOR)) -/obj/item/lipstick/attack_self(mob/user) +/obj/item/cosmetics/attack_self(mob/user) open = !open - if(open) - to_chat(user, SPAN_NOTICE("You remove the cap and twist \the [src] open.")) - else - to_chat(user, SPAN_NOTICE("You twist \the [src] closed and replace the cap.")) + show_open_message(user) update_icon() -/obj/item/lipstick/attack(atom/A, mob/user, target_zone) +/obj/item/cosmetics/proc/show_open_message(mob/user) + return + +/obj/item/cosmetics/attack(atom/A, mob/user, target_zone) if(!open || !ishuman(A)) return ..() @@ -48,84 +54,168 @@ head.write_on(user, src) return TRUE - var/obj/item/organ/external/head/head = user.get_organ(BP_HEAD, /obj/item/organ/external/head) - if(!head) + var/obj/item/organ/external/limb = user.get_organ(apply_marking_to_limb, /obj/item/organ/external/head) + if(!limb) return ..() - if(user.a_intent == I_HELP && target_zone == BP_HEAD) + if(user.a_intent == I_HELP && target_zone != apply_to_zone && istype(limb, /obj/item/organ/external/head)) + var/obj/item/organ/external/head/head = limb head.write_on(user, src.name) return TRUE - if(!head.has_lips || !isliving(user)) + if(!isliving(A) || target_zone != apply_to_zone) return ..() - var/mob/living/user_living = user - if(user_living.get_lip_colour()) //if they already have lipstick on - to_chat(user, SPAN_WARNING("You need to wipe off the old lipstick first!")) + var/decl/sprite_accessory/cosmetics/lip_decl = GET_DECL(cosmetic_type) + if(!lip_decl?.accessory_is_available(user, limb.species, limb.bodytype)) + to_chat(user, SPAN_WARNING("You can't wear this makeup!")) return TRUE - if(user == user) + var/mob/living/user_living = user + if(user_living == A) + if(user_living.get_organ_sprite_accessory(cosmetic_type, apply_marking_to_limb)) //if they already have lipstick on + to_chat(user, SPAN_WARNING("You need to wipe off your old makeup first!")) + return TRUE user.visible_message( - SPAN_NOTICE("\The [user] does their lips with \the [src]."), + SPAN_NOTICE("\The [user] does their makeup with \the [src]."), SPAN_NOTICE("You take a moment to apply \the [src]. Perfect!") ) - user_living.set_lip_colour(color) + user_living.set_organ_sprite_accessory(cosmetic_type, SAC_COSMETICS, makeup_color, apply_marking_to_limb) + return TRUE + + user_living = A + if(user_living.get_organ_sprite_accessory(cosmetic_type, apply_marking_to_limb)) //if they already have lipstick on + to_chat(user, SPAN_WARNING("You need to wipe off the old makeup first!")) return TRUE user.visible_message( - SPAN_NOTICE("\The [user] begins to do \the [user]'s lips with \the [src]."), - SPAN_NOTICE("You begin to apply \the [src].") + SPAN_NOTICE("\The [user] begins to do \the [user_living]'s makeup with \the [src]."), + SPAN_NOTICE("You begin to apply \the [src] to \the [user_living].") ) - if(do_after(user, 2 SECONDS, user) && do_after(user, 2 SECONDS, check_holding = 0, progress = 0, incapacitation_flags = INCAPACITATION_NONE)) //user needs to keep their active hand, H does not. + if(do_after(user, 2 SECONDS, user_living)) user.visible_message( - SPAN_NOTICE("\The [user] does \the [user]'s lips with \the [src]."), - SPAN_NOTICE("You apply \the [src].") + SPAN_NOTICE("\The [user] does \the [user_living]'s makeup with \the [src]."), + SPAN_NOTICE("You apply \the [src] to \the [user_living].") ) - user_living.set_lip_colour(color) + if(user_living.get_organ_sprite_accessory(cosmetic_type, SAC_COSMETICS, apply_marking_to_limb)) + return TRUE + user_living.set_organ_sprite_accessory(cosmetic_type, SAC_COSMETICS, makeup_color, apply_marking_to_limb) return TRUE //types -/obj/item/lipstick/yellow - name = "topaz lipstick" - color = "#dfdb0a" +/obj/item/cosmetics/lipstick + name = "lipstick" + desc = "An unbranded tube of lipstick." + icon = 'icons/obj/items/cosmetics/lipstick.dmi' + icon_state = "lipstick_closed" + cosmetic_type = /decl/sprite_accessory/cosmetics/lipstick + abstract_type = /obj/item/cosmetics/lipstick + base_icon_state = "lipstick" + +/obj/item/cosmetics/lipstick/show_open_message(mob/user) + if(open) + to_chat(user, SPAN_NOTICE("You remove the cap and twist \the [src] open.")) + else + to_chat(user, SPAN_NOTICE("You twist \the [src] closed and replace the cap.")) + +/obj/item/cosmetics/lipstick/red + makeup_color = "#e00606" + color_desc = "ruby" + +/obj/item/cosmetics/lipstick/yellow + makeup_color = "#dfdb0a" + color_desc = "topaz" + +/obj/item/cosmetics/lipstick/orange + makeup_color = "#db7d11" + color_desc = "agate" + +/obj/item/cosmetics/lipstick/green + makeup_color = "#218c17" + color_desc = "emerald" + +/obj/item/cosmetics/lipstick/turquoise + makeup_color = "#0098f0" + color_desc = "turquoise" + +/obj/item/cosmetics/lipstick/blue + makeup_color = "#0024f0" + color_desc = "sapphire" + +/obj/item/cosmetics/lipstick/violet + makeup_color = "#d55cd0" + color_desc = "amethyst" + +/obj/item/cosmetics/lipstick/white + makeup_color = "#d8d5d5" + color_desc = "moonstone" + +/obj/item/cosmetics/lipstick/purple + makeup_color = "#440044" + color_desc = "garnet" + +/obj/item/cosmetics/lipstick/black + makeup_color = "#2b2a2a" + color_desc = "onyx" + +/obj/item/cosmetics/eyeshadow + name = "eyeshadow" + abstract_type = /obj/item/cosmetics/eyeshadow + desc = "An unbranded tube of eyeshadow." + icon = 'icons/obj/items/cosmetics/eyeshadow.dmi' + icon_state = "eyeshadow_closed" + cosmetic_type = /decl/sprite_accessory/cosmetics/eyeshadow + abstract_type = /obj/item/cosmetics/eyeshadow + apply_to_zone = BP_EYES + base_icon_state = "eyeshadow" + +/obj/item/cosmetics/eyeshadow/show_open_message(mob/user) + if(open) + to_chat(user, SPAN_NOTICE("You pop \the [src] open and remove the brush.")) + else + to_chat(user, SPAN_NOTICE("You snap \the [src] closed and replace the brush.")) + +/obj/item/cosmetics/eyeshadow/red + makeup_color = "#e00606" + color_desc = "ruby" + +/obj/item/cosmetics/eyeshadow/yellow + makeup_color = "#dfdb0a" color_desc = "topaz" -/obj/item/lipstick/orange - name = "agate lipstick" - color = "#db7d11" +/obj/item/cosmetics/eyeshadow/orange + makeup_color = "#db7d11" color_desc = "agate" -/obj/item/lipstick/green - name = "emerald lipstick" - color = "#218c17" +/obj/item/cosmetics/eyeshadow/green + makeup_color = "#218c17" color_desc = "emerald" -/obj/item/lipstick/turquoise - name = "turquoise lipstick" - color = "#0098f0" +/obj/item/cosmetics/eyeshadow/turquoise + makeup_color = "#0098f0" color_desc = "turquoise" -/obj/item/lipstick/blue - name = "sapphire lipstick" - color = "#0024f0" +/obj/item/cosmetics/eyeshadow/blue + makeup_color = "#0024f0" color_desc = "sapphire" -/obj/item/lipstick/violet - name = "amethyst lipstick" - color = "#d55cd0" +/obj/item/cosmetics/eyeshadow/violet + makeup_color = "#d55cd0" color_desc = "amethyst" -/obj/item/lipstick/white - name = "moonstone lipstick" - color = "#d8d5d5" +/obj/item/cosmetics/eyeshadow/white + makeup_color = "#d8d5d5" color_desc = "moonstone" -/obj/item/lipstick/purple - name = "garnet lipstick" - color = "#440044" +/obj/item/cosmetics/eyeshadow/purple + makeup_color = "#440044" color_desc = "garnet" -/obj/item/lipstick/black - name = "onyx lipstick" - color = "#2b2a2a" - color_desc = "onyx" \ No newline at end of file +/obj/item/cosmetics/eyeshadow/black + makeup_color = "#2b2a2a" + color_desc = "onyx" + +/obj/item/cosmetics/eyeshadow/black + name = "onyx eyeshadow" + makeup_color = "#2b2a2a" + color_desc = "onyx" diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 6739d316d47..c4d002b75d1 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -60,7 +60,7 @@ /obj/item/storage/belt/champion, /obj/item/pickaxe/silver, /obj/item/pen/invisible, - /obj/random/lipstick, + /obj/random/makeup, /obj/item/grenade/smokebomb, /obj/item/corncob, /obj/item/poster, diff --git a/code/game/objects/items/weapons/hair_care.dm b/code/game/objects/items/weapons/hair_care.dm index 8eeb0d8e771..b35137c9015 100644 --- a/code/game/objects/items/weapons/hair_care.dm +++ b/code/game/objects/items/weapons/hair_care.dm @@ -29,11 +29,16 @@ material = /decl/material/solid/organic/plastic /obj/item/haircomb/brush/attack_self(mob/user) - if(ishuman(user) && !user.incapacitated()) - var/mob/living/carbon/human/H = user - var/hairstyle = H.get_hairstyle() + if(user.incapacitated() || !isliving(user)) + return ..() + var/mob/living/user_living = user + var/hairstyle = GET_HAIR_STYLE(user_living) + if(hairstyle) var/decl/sprite_accessory/hair/hair_style = GET_DECL(hairstyle) - if(hair_style.flags & VERY_SHORT) - H.visible_message(SPAN_NOTICE("\The [H] just sort of runs \the [src] over their scalp.")) + if(hair_style.accessory_flags & VERY_SHORT) + user_living.visible_message(SPAN_NOTICE("\The [user_living] just sort of runs \the [src] over their scalp.")) else - H.visible_message(SPAN_NOTICE("\The [H] meticulously brushes their hair with \the [src].")) \ No newline at end of file + user_living.visible_message(SPAN_NOTICE("\The [user_living] meticulously brushes their hair with \the [src].")) + else + to_chat(user_living, SPAN_WARNING("You don't have any hair to brush!")) + return TRUE diff --git a/code/game/objects/items/weapons/storage/wall_mirror.dm b/code/game/objects/items/weapons/storage/wall_mirror.dm index 4ae11605eb1..cad3a4fa695 100644 --- a/code/game/objects/items/weapons/storage/wall_mirror.dm +++ b/code/game/objects/items/weapons/storage/wall_mirror.dm @@ -33,8 +33,8 @@ /obj/item/haircomb/random, /obj/item/haircomb/brush, /obj/random/medical/lite, - /obj/item/lipstick, /obj/random/lipstick, + /obj/random/eyeshadow, /obj/random/soap, /obj/item/chems/spray/cleaner/deodorant, /obj/item/towel/random diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index 74b5a06e881..cd64e3b6d1b 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -10,7 +10,7 @@ /obj/item/cash, /obj/item/card, /obj/item/clothing/mask/smokable, - /obj/item/lipstick, + /obj/item/cosmetics, /obj/item/haircomb, /obj/item/mirror, /obj/item/clothing/accessory/locket, diff --git a/code/game/objects/random/subtypes/misc.dm b/code/game/objects/random/subtypes/misc.dm index 8af5db740a3..e92a3b26983 100644 --- a/code/game/objects/random/subtypes/misc.dm +++ b/code/game/objects/random/subtypes/misc.dm @@ -381,23 +381,71 @@ /obj/random/lipstick name = "random lipstick" desc = "This is a tube of lipstick." - icon = 'icons/obj/items/lipstick.dmi' - icon_state = "lipstick_0" + icon = 'icons/obj/items/cosmetics/lipstick.dmi' + icon_state = "lipstick_closed" /obj/random/lipstick/spawn_choices() var/static/list/spawnable_choices = list( - /obj/item/lipstick, - /obj/item/lipstick/blue, - /obj/item/lipstick/green, - /obj/item/lipstick/turquoise, - /obj/item/lipstick/violet, - /obj/item/lipstick/yellow, - /obj/item/lipstick/orange, - /obj/item/lipstick/white, - /obj/item/lipstick/black + /obj/item/cosmetics/lipstick/red, + /obj/item/cosmetics/lipstick/blue, + /obj/item/cosmetics/lipstick/green, + /obj/item/cosmetics/lipstick/turquoise, + /obj/item/cosmetics/lipstick/violet, + /obj/item/cosmetics/lipstick/yellow, + /obj/item/cosmetics/lipstick/orange, + /obj/item/cosmetics/lipstick/white, + /obj/item/cosmetics/lipstick/black ) return spawnable_choices +/obj/random/eyeshadow + name = "random eyeshadow" + desc = "This is a tube of eyeshadow." + icon = 'icons/obj/items/cosmetics/eyeshadow.dmi' + icon_state = "eyeshadow_closed" + +/obj/random/eyeshadow/spawn_choices() + var/static/list/spawnable_choices = list( + /obj/item/cosmetics/eyeshadow/red, + /obj/item/cosmetics/eyeshadow/blue, + /obj/item/cosmetics/eyeshadow/green, + /obj/item/cosmetics/eyeshadow/turquoise, + /obj/item/cosmetics/eyeshadow/violet, + /obj/item/cosmetics/eyeshadow/yellow, + /obj/item/cosmetics/eyeshadow/orange, + /obj/item/cosmetics/eyeshadow/white, + /obj/item/cosmetics/eyeshadow/black + ) + return spawnable_choices + +/obj/random/makeup + name = "random makeup" + desc = "This is a tube of makeup." + icon = 'icons/obj/items/cosmetics/lipstick.dmi' + icon_state = "lipstick_closed" + +/obj/random/makeup/spawn_choices() + var/static/list/spawnable_choices = list( + /obj/item/cosmetics/lipstick/red, + /obj/item/cosmetics/lipstick/blue, + /obj/item/cosmetics/lipstick/green, + /obj/item/cosmetics/lipstick/turquoise, + /obj/item/cosmetics/lipstick/violet, + /obj/item/cosmetics/lipstick/yellow, + /obj/item/cosmetics/lipstick/orange, + /obj/item/cosmetics/lipstick/white, + /obj/item/cosmetics/lipstick/black, + /obj/item/cosmetics/eyeshadow/red, + /obj/item/cosmetics/eyeshadow/blue, + /obj/item/cosmetics/eyeshadow/green, + /obj/item/cosmetics/eyeshadow/turquoise, + /obj/item/cosmetics/eyeshadow/violet, + /obj/item/cosmetics/eyeshadow/yellow, + /obj/item/cosmetics/eyeshadow/orange, + /obj/item/cosmetics/eyeshadow/white, + /obj/item/cosmetics/eyeshadow/black + ) + return spawnable_choices /obj/random/crayon name = "random crayon" diff --git a/code/game/objects/structures/fountain.dm b/code/game/objects/structures/fountain.dm index 78247136d23..76e228ca6a2 100644 --- a/code/game/objects/structures/fountain.dm +++ b/code/game/objects/structures/fountain.dm @@ -74,7 +74,7 @@ else to_chat(user, "You touch the fountain. All the memories of your life seem to fade into the distant past as seconds drag like years. You feel the inexplicable sensation of your skin tightening and thinning across your entire body as your muscles degrade and your joints weaken. Time returns to its 'normal' pace. You can only just barely remember touching the fountain.") user.became_older = TRUE - user.set_hair_colour(COLOR_GRAY80) + SET_HAIR_COLOUR(user, COLOR_GRAY80, FALSE) var/max_age = age.standalone_value_descriptors[age.standalone_value_descriptors[length(age.standalone_value_descriptors)]] if(new_age >= max_age) to_chat(user, "The burden of the years is too much, and you are reduced to dust.") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index bdb88717b15..084df369219 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -763,12 +763,12 @@ var/global/list/admin_verbs_mod = list( var/update_hair = FALSE var/new_facial = input("Please select facial hair color.", "Character Generation") as color if(new_facial) - M.set_facial_hair_colour(new_facial, skip_update = TRUE) + SET_FACIAL_HAIR_COLOUR(M, new_facial, TRUE) update_hair = TRUE var/new_hair = input("Please select hair color.", "Character Generation") as color if(new_hair) - M.set_hair_colour(new_hair, skip_update = TRUE) + SET_HAIR_COLOUR(M, new_hair, TRUE) update_hair = TRUE var/new_eyes = input("Please select eye color.", "Character Generation") as color @@ -788,13 +788,13 @@ var/global/list/admin_verbs_mod = list( // hair var/new_hairstyle = input(usr, "Select a hair style", "Grooming") as null|anything in decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/hair) if(new_hairstyle) - M.set_hairstyle(new_hairstyle, skip_update = TRUE) + SET_HAIR_STYLE(M, new_hairstyle, TRUE) update_hair = TRUE // facial hair var/new_fstyle = input(usr, "Select a facial hair style", "Grooming") as null|anything in decls_repository.get_decl_paths_of_subtype(/decl/sprite_accessory/facial_hair) if(new_fstyle) - M.set_facial_hairstyle(new_fstyle, skip_update = TRUE) + SET_FACIAL_HAIR_STYLE(M, new_fstyle, TRUE) update_hair = TRUE var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female", "Neuter") diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 77ce2c0c676..1f2adca4cf7 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -41,6 +41,7 @@ return INITIALIZE_HINT_QDEL /obj/abstract/landmark/corpse/proc/randomize_appearance(var/mob/living/carbon/human/M, species_choice) + if((spawn_flags & CORPSE_SPAWNER_RANDOM_GENDER)) if(species_choice in genders_per_species) M.set_gender(pick(genders_per_species[species_choice]), TRUE) @@ -59,24 +60,30 @@ else M.randomize_skin_color() + var/decl/species/species_decl = get_species_by_key(species_choice) + var/decl/bodytype/root_bodytype = M.get_bodytype() + var/update_hair = FALSE if((spawn_flags & CORPSE_SPAWNER_RANDOM_HAIR_COLOR)) if(species_choice in hair_colors_per_species) - M.set_hair_colour(pick(hair_colors_per_species[species_choice])) + SET_HAIR_COLOUR(M, pick(hair_colors_per_species[species_choice]), TRUE) else - M.randomize_hair_color() - M.set_facial_hair_colour(M.get_hair_colour()) - + SET_HAIR_COLOUR(M, get_random_colour(), TRUE) + SET_FACIAL_HAIR_COLOUR(M, GET_HAIR_COLOUR(M), TRUE) + update_hair = TRUE if((spawn_flags & CORPSE_SPAWNER_RANDOM_HAIR_STYLE)) if(species_choice in hair_styles_per_species) - M.set_hairstyle(pick(hair_styles_per_species[species_choice])) + SET_HAIR_STYLE(M, pick(hair_styles_per_species[species_choice]), TRUE) else - M.randomize_hair_style() - + SET_HAIR_STYLE(M, pick(species_decl.get_available_accessory_types(root_bodytype, SAC_HAIR)), TRUE) + update_hair = TRUE if((spawn_flags & CORPSE_SPAWNER_RANDOM_FACIAL_STYLE)) if(species_choice in facial_styles_per_species) - M.set_facial_hairstyle(pick(facial_styles_per_species[species_choice])) + SET_FACIAL_HAIR_STYLE(M, pick(facial_styles_per_species[species_choice]), TRUE) else - M.randomize_facial_hair_style() + SET_FACIAL_HAIR_STYLE(M, pick(species_decl.get_available_accessory_types(root_bodytype, SAC_FACIAL_HAIR)), TRUE) + update_hair = TRUE + if(update_hair) + M.update_hair() if((spawn_flags & CORPSE_SPAWNER_RANDOM_EYE_COLOR)) if(species_choice in eye_colors_per_species) diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index 8823b103aa4..7383f278680 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -92,12 +92,8 @@ pref.species = choice pref.sanitize_preferences() - //reset hairstyle prefs - ResetAllHair() - // reset colors var/decl/species/mob_species = pref.get_species_decl() mob_species.handle_post_species_pref_set(pref) - // reset markings var/decl/bodytype/mob_bodytype = pref.get_bodytype_decl() mob_bodytype.handle_post_bodytype_pref_set(pref) diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 81386b8b5f3..493af4ce191 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -142,13 +142,7 @@ pref.bodytype = new_body.name if(new_body.associated_gender) // Set to default for male/female to avoid confusing people pref.gender = new_body.associated_gender - var/decl/sprite_accessory/hair/hairstyle = GET_DECL(pref.h_style) - if(!hairstyle?.accessory_is_available(null, S, new_body)) - pref.h_style = new_body.default_h_style - var/decl/sprite_accessory/hair/facialhairstyle = GET_DECL(pref.f_style) - if(!facialhairstyle?.accessory_is_available(null, S, new_body)) - pref.f_style = new_body.default_f_style - new_body.handle_post_bodytype_pref_set(pref) + new_body.handle_post_bodytype_pref_set(pref) return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["spawnpoint"]) diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index 2582487bc45..e174b9f4519 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -2,15 +2,10 @@ var/species var/blood_type //blood type - var/h_style = /decl/sprite_accessory/hair/bald - var/f_style = /decl/sprite_accessory/facial_hair/shaved - - var/hair_colour = COLOR_BLACK - var/skin_colour = COLOR_BLACK - var/facial_hair_colour = COLOR_BLACK var/eye_colour = COLOR_BLACK + var/skin_colour = COLOR_BLACK var/skin_tone = 0 //Skin tone - var/list/body_markings = list() + var/list/sprite_accessories = list() var/list/appearance_descriptors = list() var/equip_preview_mob = EQUIP_PREVIEW_ALL @@ -23,8 +18,6 @@ /datum/category_item/player_setup_item/physical/body/load_character(datum/pref_record_reader/R) - pref.hair_colour = R.read("hair_colour") - pref.facial_hair_colour = R.read("facial_hair_colour") pref.skin_colour = R.read("skin_colour") pref.eye_colour = R.read("eye_colour") pref.skin_tone = R.read("skin_tone") @@ -32,47 +25,68 @@ pref.appearance_descriptors = R.read("appearance_descriptors") pref.bgstate = R.read("bgstate") - // Get h_style type. - var/decl/h_style_decl = decls_repository.get_decl_by_id_or_var(R.read("hair_style_name"), /decl/sprite_accessory/hair) - pref.h_style = istype(h_style_decl) ? h_style_decl.type : /decl/sprite_accessory/hair/bald - // Get f_style type. - var/decl/f_style_decl = decls_repository.get_decl_by_id_or_var(R.read("facial_style_name"), /decl/sprite_accessory/facial_hair) - pref.f_style = istype(f_style_decl) ? f_style_decl.type : /decl/sprite_accessory/facial_hair/shaved - // Get markings type. + // Load all of our saved accessories. + pref.sprite_accessories = list() + var/list/load_accessories = R.read("sprite_accessories") + for(var/category_uid in load_accessories) + var/decl/sprite_accessory_category/accessory_category = decls_repository.get_decl_by_id_or_var(category_uid, /decl/sprite_accessory_category) + if(!istype(accessory_category)) + continue + pref.sprite_accessories[accessory_category.type] = list() + for(var/accessory_name in load_accessories[category_uid]) + var/decl/sprite_accessory/loaded_accessory = decls_repository.get_decl_by_id_or_var(accessory_name, accessory_category.base_accessory_type) + if(istype(loaded_accessory, accessory_category.base_accessory_type)) + pref.sprite_accessories[accessory_category.type][loaded_accessory.type] = load_accessories[category_uid][accessory_name] + + // Grandfather in pre-existing hair and markings. + var/decl/style_decl + var/decl/sprite_accessory_category/accessory_cat + var/hair_name = R.read("hair_style_name") + if(hair_name) + accessory_cat = GET_DECL(SAC_HAIR) + style_decl = decls_repository.get_decl_by_id_or_var(hair_name, accessory_cat.base_accessory_type) + if(style_decl) + LAZYINITLIST(pref.sprite_accessories[accessory_cat.type]) + pref.sprite_accessories[accessory_cat.type][style_decl.type] = R.read("hair_colour") || COLOR_BLACK + + hair_name = R.read("facial_style_name") + if(hair_name) + accessory_cat = GET_DECL(SAC_FACIAL_HAIR) + style_decl = decls_repository.get_decl_by_id_or_var(hair_name, accessory_cat.base_accessory_type) + if(style_decl) + LAZYINITLIST(pref.sprite_accessories[accessory_cat.type]) + pref.sprite_accessories[accessory_cat.type][style_decl.type] = R.read("facial_hair_colour") || COLOR_BLACK + var/list/load_markings = R.read("body_markings") - pref.body_markings = list() if(length(load_markings)) - for(var/marking in load_markings) - var/decl/sprite_accessory/marking/loaded_marking = decls_repository.get_decl_by_id_or_var(marking, /decl/sprite_accessory/marking) - if(istype(loaded_marking)) - pref.body_markings[loaded_marking.type] = load_markings[marking] + accessory_cat = GET_DECL(SAC_MARKINGS) + for(var/accessory in load_markings) + style_decl = decls_repository.get_decl_by_id_or_var(accessory, accessory_cat.base_accessory_type) + if(style_decl) + LAZYINITLIST(pref.sprite_accessories[accessory_cat.type]) + pref.sprite_accessories[accessory_cat.type][style_decl.type] = load_markings[accessory] || COLOR_BLACK /datum/category_item/player_setup_item/physical/body/save_character(datum/pref_record_writer/W) + + var/list/save_accessories = list() + for(var/acc_cat in pref.sprite_accessories) + var/decl/sprite_accessory_category/accessory_category = GET_DECL(acc_cat) + save_accessories[accessory_category.uid] = list() + for(var/acc in pref.sprite_accessories[acc_cat]) + var/decl/sprite_accessory/accessory = GET_DECL(acc) + save_accessories[accessory_category.uid][accessory.uid] = pref.sprite_accessories[acc_cat][acc] + + W.write("sprite_accessories", save_accessories) W.write("skin_tone", pref.skin_tone) - W.write("hair_colour", pref.hair_colour) - W.write("facial_hair_colour", pref.facial_hair_colour) W.write("skin_colour", pref.skin_colour) W.write("eye_colour", pref.eye_colour) W.write("b_type", pref.blood_type) W.write("appearance_descriptors", pref.appearance_descriptors) W.write("bgstate", pref.bgstate) - // Get names of sprite accessories to serialize. - var/decl/sprite_accessory/sprite = GET_DECL(pref.h_style) - W.write("hair_style_name", sprite.uid) - sprite = GET_DECL(pref.f_style) - W.write("facial_style_name", sprite.uid) - var/list/body_marking_names = list() - for(var/marking in pref.body_markings) - sprite = GET_DECL(marking) - body_marking_names[sprite.uid] = pref.body_markings[marking] - W.write("body_markings", body_marking_names) - /datum/category_item/player_setup_item/physical/body/sanitize_character() pref.skin_colour = pref.skin_colour || COLOR_BLACK - pref.hair_colour = pref.hair_colour || COLOR_BLACK - pref.facial_hair_colour = pref.facial_hair_colour || COLOR_BLACK pref.eye_colour = pref.eye_colour || COLOR_BLACK pref.blood_type = sanitize_text(pref.blood_type, initial(pref.blood_type)) @@ -88,17 +102,27 @@ var/low_skin_tone = mob_bodytype ? (35 - mob_bodytype.max_skin_tone()) : -185 sanitize_integer(pref.skin_tone, low_skin_tone, 34, initial(pref.skin_tone)) - if(!ispath(pref.h_style, /decl/sprite_accessory/hair)) - pref.h_style = initial(pref.h_style) - - if(!ispath(pref.f_style, /decl/sprite_accessory/facial_hair)) - pref.f_style = initial(pref.f_style) - - if(!islist(pref.body_markings)) - pref.body_markings = list() - for(var/marking in pref.body_markings) - if(!ispath(marking, /decl/sprite_accessory/marking)) - pref.body_markings -= marking + var/pref_mob = preference_mob() + LAZYINITLIST(pref.sprite_accessories) + for(var/acc_cat in pref.sprite_accessories) + if(!(acc_cat in mob_species.available_accessory_categories)) + pref.sprite_accessories -= acc_cat + continue + var/decl/sprite_accessory_category/accessory_category = GET_DECL(acc_cat) + for(var/acc in pref.sprite_accessories[acc_cat]) + var/decl/sprite_accessory/accessory = GET_DECL(acc) + if(!istype(accessory, accessory_category.base_accessory_type) || !accessory.accessory_is_available(pref_mob, mob_species, mob_bodytype)) + pref.sprite_accessories[acc_cat] -= acc + + for(var/accessory_category in mob_species.available_accessory_categories) + LAZYINITLIST(pref.sprite_accessories[accessory_category]) + var/decl/sprite_accessory_category/accessory_cat_decl = GET_DECL(accessory_category) + if(accessory_cat_decl.single_selection) + var/list/current_accessories = pref.sprite_accessories[accessory_category] + if(!length(current_accessories)) + current_accessories[accessory_cat_decl.default_accessory] = accessory_cat_decl.default_accessory_color + else if(length(current_accessories) > 1) + current_accessories.Cut(2) var/list/last_descriptors = list() if(islist(pref.appearance_descriptors)) @@ -124,10 +148,6 @@ . += "Blood Type: [pref.blood_type]
" . += "Randomize Appearance
" - if(mob_bodytype.appearance_flags & HAS_A_SKIN_TONE) - . += "Skin Tone: [-pref.skin_tone + 35]/[mob_bodytype.max_skin_tone()]
" - . += "
" - if(LAZYLEN(pref.appearance_descriptors)) . += "

Physical Appearance

" . += "" @@ -148,65 +168,80 @@ . += "" . += "
" - . += "

Colouration

" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - if(mob_bodytype.appearance_flags & HAS_EYE_COLOR) - . += "" - . += "" - . += "" - . += "" - if(mob_bodytype.appearance_flags & HAS_SKIN_COLOR) - . += "" - . += "" - . += "" - . += "" - . += "
Hair" - - var/const/up_arrow = "⇧" - var/const/down_arrow = "⇩" - var/const/left_arrow = "⇦" - var/const/right_arrow = "⇨" - - if(mob_bodytype.appearance_flags & HAS_HAIR_COLOR) - . += "[COLORED_SQUARE(pref.hair_colour)] Change" - . += "[left_arrow][GET_DECL(pref.h_style)][right_arrow]
Facial" - if(mob_bodytype.appearance_flags & HAS_HAIR_COLOR) - . += "[COLORED_SQUARE(pref.facial_hair_colour)] Change" - . += "[left_arrow][GET_DECL(pref.f_style)][right_arrow]
Eyes[COLORED_SQUARE(pref.eye_colour)] Change" - . += "
Body[COLORED_SQUARE(pref.skin_colour)] Change" - . += "
" + if((mob_bodytype.appearance_flags & (HAS_EYE_COLOR|HAS_SKIN_COLOR|HAS_A_SKIN_TONE)) || length(mob_species.available_accessory_categories)) + + . += "

Colouration and accessories

" + . += "" + + if(mob_bodytype.appearance_flags & HAS_A_SKIN_TONE) + . += "" + . += "" + . += "" + . += "" + + if(mob_bodytype.appearance_flags & HAS_SKIN_COLOR) + . += "" + . += "" + . += "" + . += "" + + if(mob_bodytype.appearance_flags & HAS_EYE_COLOR) + . += "" + . += "" + . += "" + . += "" + + var/const/up_arrow = "⇧" + var/const/down_arrow = "⇩" + var/const/left_arrow = "⇦" + var/const/right_arrow = "⇨" + + for(var/accessory_category in mob_species.available_accessory_categories) + var/decl/sprite_accessory_category/accessory_cat_decl = GET_DECL(accessory_category) + var/list/current_accessories = LAZYACCESS(pref.sprite_accessories, accessory_category) + var/cat_decl_ref = "\ref[accessory_cat_decl]" + if(accessory_cat_decl.single_selection) + var/current_accessory = length(current_accessories) ? current_accessories[1] : accessory_cat_decl.default_accessory + var/accessory_color = length(current_accessories) ? current_accessories[current_accessory] : accessory_cat_decl.default_accessory_color + var/decl/sprite_accessory/accessory_decl = GET_DECL(current_accessory) + var/acc_decl_ref = "\ref[accessory_decl]" + . += "" + . += "" + . += "" + . += "" + . += "" + . += "" + . += "" + continue + + . += "" + . += "" + . += "" + . += "" + var/i = 0 + for(var/accessory in current_accessories) + i++ + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + var/acc_decl_ref = "\ref[accessory_decl]" + . += "" + . += "" + . += "" + . += "" + . += "" + . += "" + . += "" + if(isnull(accessory_cat_decl.max_selections) || i < accessory_cat_decl.max_selections) + . += "" - . += "

Markings

" - . += "
Skin tone[-pref.skin_tone + 35]/[mob_bodytype.max_skin_tone()]" + . += "
Skin color[COLORED_SQUARE(pref.skin_colour)] Change" + . += "
Eyes[COLORED_SQUARE(pref.eye_colour)] Change" + . += "
[accessory_cat_decl.name][COLORED_SQUARE(accessory_color)] Change[left_arrow][accessory_decl.name][right_arrow]
[accessory_cat_decl.name]
Remove[COLORED_SQUARE(current_accessories[accessory])] Change[up_arrow][accessory_decl.name][down_arrow]
Add marking
" - for(var/M in pref.body_markings) - var/decl/sprite_accessory/mark = GET_DECL(M) - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" . += "
Remove[COLORED_SQUARE(pref.body_markings[M])] Change[up_arrow][mark.name][down_arrow]
Add marking
" . = jointext(.,null) /datum/category_item/player_setup_item/physical/body/OnTopic(var/href,var/list/href_list, var/mob/user) + var/decl/species/mob_species = get_species_by_key(pref.species) var/decl/bodytype/mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype if(href_list["set_descriptor"]) @@ -225,7 +260,7 @@ return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["random"]) - pref.randomize_appearance_and_body_for() + pref.randomize_appearance_and_body_for(preference_mob()) return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["blood_type"]) @@ -236,71 +271,92 @@ pref.blood_type = new_b_type return TOPIC_REFRESH - else if(href_list["hair_color"]) - if(!(mob_bodytype.appearance_flags & HAS_HAIR_COLOR)) + else if (href_list["acc_decl"] || href_list["acc_cat_decl"]) + + var/decl/sprite_accessory/accessory_decl = locate(href_list["acc_decl"]) + var/decl/sprite_accessory_category/accessory_category = locate(href_list["acc_cat_decl"]) + if(!istype(accessory_decl) && !istype(accessory_category)) return TOPIC_NOACTION - var/new_hair = input(user, "Choose your character's hair colour:", CHARACTER_PREFERENCE_INPUT_TITLE, pref.hair_colour) as color|null - mob_species = get_species_by_key(pref.species) - mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype - if(new_hair && (mob_bodytype.appearance_flags & HAS_HAIR_COLOR) && CanUseTopic(user)) - pref.hair_colour = new_hair + if(!istype(accessory_category)) + accessory_category = GET_DECL(accessory_decl.accessory_category) + if(!(accessory_category.type in mob_species.available_accessory_categories)) + return TOPIC_NOACTION + + // Ensure we have a list for the category. + var/list/current_accessories = pref.sprite_accessories[accessory_category.type] + if(!current_accessories) + current_accessories = list() + pref.sprite_accessories[accessory_category.type] = current_accessories + + if(href_list["acc_color"]) + + if(!istype(accessory_decl)) + return TOPIC_NOACTION + var/cur_color = current_accessories[accessory_decl.type] || COLOR_BLACK + var/acc_color = input(user, "Choose a colour for your [accessory_decl.name]: ", CHARACTER_PREFERENCE_INPUT_TITLE, cur_color) as color|null + if(!acc_color || acc_color == cur_color || !(accessory_decl.type in current_accessories)) + return TOPIC_NOACTION + if(accessory_category.single_selection) + current_accessories.Cut() + current_accessories[accessory_decl.type] = acc_color return TOPIC_REFRESH_UPDATE_PREVIEW - else if(href_list["hair_style"]) + else if(href_list["acc_style"]) - var/decl/sprite_accessory/new_h_style = input(user, "Choose your character's hair style:", CHARACTER_PREFERENCE_INPUT_TITLE, pref.h_style) as null|anything in mob_species.get_hair_styles(mob_bodytype) - mob_species = get_species_by_key(pref.species) - mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype - if(new_h_style && CanUseTopic(user) && (new_h_style in mob_species.get_hair_styles(mob_bodytype))) - pref.h_style = new_h_style.type + var/decl/sprite_accessory/new_accessory = input(user, "Choose an accessory:", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in pref.get_usable_sprite_accessories(preference_mob(), mob_species, mob_bodytype, accessory_category.type, current_accessories - accessory_decl.type) + if(!(new_accessory in pref.get_usable_sprite_accessories(preference_mob(), mob_species, mob_bodytype, accessory_category.type, current_accessories))) + return TOPIC_NOACTION + var/style_colour = (accessory_decl && current_accessories[accessory_decl.type]) || accessory_category.default_accessory_color + if(accessory_category.single_selection) + current_accessories.Cut() + current_accessories[new_accessory.type] = style_colour return TOPIC_REFRESH_UPDATE_PREVIEW - else if(href_list["hair_next"] || href_list["hair_prev"]) - var/decl/sprite_accessory/current_hair = GET_DECL(pref.h_style) - var/list/available_hair = mob_species.get_hair_styles(mob_bodytype) - if(current_hair in available_hair) - if(href_list["hair_next"]) - current_hair = next_in_list(current_hair, available_hair) - else if(href_list["hair_prev"]) - current_hair = previous_in_list(current_hair, available_hair) - if(istype(current_hair) && pref.h_style != current_hair.type) - pref.h_style = current_hair.type + else if(accessory_category.single_selection && (href_list["acc_next"] || href_list["acc_prev"])) + + if(!length(current_accessories) || !istype(accessory_decl)) + return TOPIC_NOACTION + var/decl/sprite_accessory/next_accessory_decl + var/style_colour = current_accessories[accessory_decl.type] + var/list/available_accessories = pref.get_usable_sprite_accessories(preference_mob(), mob_species, mob_bodytype, accessory_category.type, current_accessories - accessory_decl.type) + if(href_list["acc_next"]) + next_accessory_decl = next_in_list(accessory_decl, available_accessories) + else if(href_list["acc_prev"]) + next_accessory_decl = previous_in_list(accessory_decl, available_accessories) + + if(istype(next_accessory_decl) && accessory_decl != next_accessory_decl) + current_accessories.Cut() + current_accessories[next_accessory_decl.type] = style_colour return TOPIC_REFRESH_UPDATE_PREVIEW + return TOPIC_NOACTION - return TOPIC_NOACTION - else if(href_list["facial_style"]) + else if(!accessory_category.single_selection) - var/decl/sprite_accessory/new_f_style = input(user, "Choose your character's facial-hair style:", CHARACTER_PREFERENCE_INPUT_TITLE, GET_DECL(pref.f_style)) as null|anything in mob_species.get_facial_hair_styles(mob_bodytype) - mob_species = get_species_by_key(pref.species) - mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype - if(new_f_style && CanUseTopic(user) && (new_f_style in mob_species.get_facial_hair_styles(mob_bodytype))) - pref.f_style = new_f_style.type - return TOPIC_REFRESH_UPDATE_PREVIEW + if(!istype(accessory_decl)) + return TOPIC_NOACTION - else if(href_list["facial_next"] || href_list["facial_prev"]) - - var/decl/sprite_accessory/current_facial_hair = GET_DECL(pref.f_style) - var/list/available_facial_hair = mob_species.get_facial_hair_styles(mob_bodytype) - if(current_facial_hair in available_facial_hair) - if(href_list["facial_next"]) - current_facial_hair = next_in_list(current_facial_hair, available_facial_hair) - else if(href_list["facial_prev"]) - current_facial_hair = previous_in_list(current_facial_hair, available_facial_hair) - if(istype(current_facial_hair) && pref.f_style != current_facial_hair.type) - pref.f_style = current_facial_hair.type - return TOPIC_REFRESH_UPDATE_PREVIEW + if(href_list["acc_remove"]) - return TOPIC_NOACTION + current_accessories -= accessory_decl.type + return TOPIC_REFRESH_UPDATE_PREVIEW - else if(href_list["facial_color"]) - if(!(mob_bodytype.appearance_flags & HAS_HAIR_COLOR)) - return TOPIC_NOACTION - var/new_facial = input(user, "Choose your character's facial-hair colour:", CHARACTER_PREFERENCE_INPUT_TITLE, pref.facial_hair_colour) as color|null - mob_species = get_species_by_key(pref.species) - mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype - if(new_facial && (mob_bodytype.appearance_flags & HAS_HAIR_COLOR) && CanUseTopic(user)) - pref.facial_hair_colour = new_facial - return TOPIC_REFRESH_UPDATE_PREVIEW + else if(href_list["acc_move_down"] || href_list["acc_move_up"]) + + if(!length(current_accessories)) + return TOPIC_NOACTION + var/current_index = current_accessories.Find(accessory_decl.type) + if(href_list["acc_move_up"] && current_index <= 1) + return TOPIC_NOACTION + else if(href_list["acc_move_down"] && current_index >= length(current_accessories)) + return TOPIC_NOACTION + var/accessory_color = current_accessories[accessory_decl.type] + current_accessories -= accessory_decl.type + if(href_list["acc_move_up"]) + current_accessories.Insert(current_index-1, accessory_decl.type) + else if(href_list["acc_move_down"]) + current_accessories.Insert(current_index+1, accessory_decl.type) + current_accessories[accessory_decl.type] = accessory_color + return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["eye_color"]) if(!(mob_bodytype.appearance_flags & HAS_EYE_COLOR)) @@ -332,77 +388,19 @@ pref.skin_colour = new_skin return TOPIC_REFRESH_UPDATE_PREVIEW - //TODO SPRITE ACCESSORY UPDATE - else if(href_list["marking_style"]) - - var/decl/sprite_accessory/new_marking = input(user, "Choose a body marking:", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in get_usable_markings(preference_mob(), mob_species, mob_bodytype, pref.body_markings) - if(new_marking && CanUseTopic(user)) - mob_species = get_species_by_key(pref.species) - mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype - if(new_marking in get_usable_markings(preference_mob(), mob_species, mob_bodytype, pref.body_markings)) - pref.body_markings[new_marking.type] = COLOR_BLACK - return TOPIC_REFRESH_UPDATE_PREVIEW - - else if(href_list["marking_remove"]) - var/decl/sprite_accessory/M = locate(href_list["marking_remove"]) - pref.body_markings -= M.type - return TOPIC_REFRESH_UPDATE_PREVIEW - - else if(href_list["marking_color"]) - var/decl/sprite_accessory/M = locate(href_list["marking_color"]) - var/mark_color = input(user, "Choose the [M] color: ", CHARACTER_PREFERENCE_INPUT_TITLE, pref.body_markings[M.type]) as color|null - if(mark_color && CanUseTopic(user)) - pref.body_markings[M.type] = "[mark_color]" - return TOPIC_REFRESH_UPDATE_PREVIEW - - else if(href_list["marking_move_down"]) - var/decl/sprite_accessory/M = locate(href_list["marking_move_down"]) - if(istype(M)) - var/current_index = pref.body_markings.Find(M.type) - if(current_index < length(pref.body_markings)) - var/marking_color = pref.body_markings[M.type] - pref.body_markings -= M.type - pref.body_markings.Insert(current_index+1, M.type) - pref.body_markings[M.type] = marking_color - return TOPIC_REFRESH_UPDATE_PREVIEW - return TOPIC_NOACTION - - else if(href_list["marking_move_up"]) - var/decl/sprite_accessory/M = locate(href_list["marking_move_up"]) - if(istype(M)) - var/current_index = pref.body_markings.Find(M.type) - if(current_index > 1) - var/marking_color = pref.body_markings[M.type] - pref.body_markings -= M.type - pref.body_markings.Insert(current_index-1, M.type) - pref.body_markings[M.type] = marking_color - return TOPIC_REFRESH_UPDATE_PREVIEW - return TOPIC_NOACTION - -/datum/category_item/player_setup_item/physical/body/proc/get_usable_markings(mob/pref_mob, decl/species/mob_species, decl/bodytype/mob_bodytype, list/existing_markings) - var/list/disallowed_markings = list() - for (var/M in existing_markings) - var/decl/sprite_accessory/marking/mark_style = GET_DECL(M) - if(length(mark_style.disallows_accessories)) - disallowed_markings |= mark_style.disallows_accessories - var/list/all_markings = decls_repository.get_decls_of_subtype(/decl/sprite_accessory/marking) - for(var/M in all_markings) - if(M in existing_markings) +/datum/preferences/proc/get_usable_sprite_accessories(mob/pref_mob, decl/species/mob_species, decl/bodytype/mob_bodytype, accessory_category, list/existing_accessories) + var/decl/sprite_accessory_category/accessory_category_decl = GET_DECL(accessory_category) + if(!istype(accessory_category_decl)) + return + var/list/disallowed_accessories = list() + for (var/accessory in existing_accessories) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + if(length(accessory_decl.disallows_accessories)) + disallowed_accessories |= accessory_decl.disallows_accessories + var/list/all_accessories = decls_repository.get_decls_of_subtype(accessory_category_decl.base_accessory_type) + for(var/accessory in all_accessories) + if(accessory in existing_accessories) continue - var/decl/sprite_accessory/accessory = all_markings[M] - if(!is_type_in_list(accessory, disallowed_markings) && accessory.accessory_is_available(pref_mob, mob_species, mob_bodytype)) - LAZYADD(., accessory) - -/datum/category_item/player_setup_item/proc/ResetAllHair() - ResetHair() - ResetFacialHair() - -/datum/category_item/player_setup_item/proc/ResetHair() - var/decl/species/mob_species = get_species_by_key(pref.species) - var/list/valid_hairstyles = mob_species?.get_hair_style_types(pref.get_bodytype_decl()) - pref.h_style = length(valid_hairstyles) ? pick(valid_hairstyles) : initial(pref.h_style) - -/datum/category_item/player_setup_item/proc/ResetFacialHair() - var/decl/species/mob_species = get_species_by_key(pref.species) - var/list/valid_facialhairstyles = mob_species?.get_facial_hair_styles(pref.get_bodytype_decl()) - pref.f_style = length(valid_facialhairstyles) ? pick(valid_facialhairstyles) : initial(pref.f_style) + var/decl/sprite_accessory/accessory_decl = all_accessories[accessory] + if(istype(accessory_decl) && !is_type_in_list(accessory_decl, disallowed_accessories) && accessory_decl.accessory_is_available(pref_mob, mob_species, mob_bodytype)) + LAZYADD(., accessory_decl) diff --git a/code/modules/client/preference_setup/loadout/lists/misc.dm b/code/modules/client/preference_setup/loadout/lists/misc.dm index a6543d4d4a2..ace1b4b5f49 100644 --- a/code/modules/client/preference_setup/loadout/lists/misc.dm +++ b/code/modules/client/preference_setup/loadout/lists/misc.dm @@ -64,8 +64,13 @@ /decl/loadout_option/lipstick name = "lipstick selection" - path = /obj/item/lipstick - loadout_flags = GEAR_HAS_TYPE_SELECTION + path = /obj/item/cosmetics/lipstick + loadout_flags = GEAR_HAS_SUBTYPE_SELECTION + +/decl/loadout_option/eyeshadow + name = "eyeshadow selection" + path = /obj/item/cosmetics/eyeshadow + loadout_flags = GEAR_HAS_SUBTYPE_SELECTION /decl/loadout_option/comb name = "plastic comb" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index d46d9506d3d..ae41dcae536 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -382,12 +382,6 @@ var/global/list/time_prefs_fixed = list() character.set_eye_colour(eye_colour, skip_update = TRUE) - character.set_hairstyle(h_style, skip_update = TRUE) - character.set_hair_colour(hair_colour, skip_update = TRUE) - - character.set_facial_hairstyle(f_style, skip_update = TRUE) - character.set_facial_hair_colour(facial_hair_colour, skip_update = TRUE) - character.set_skin_colour(skin_colour, skip_update = TRUE) character.skin_tone = skin_tone @@ -409,16 +403,16 @@ var/global/list/time_prefs_fixed = list() character.backpack_setup = new(backpack, backpack_metadata["[backpack]"]) for(var/obj/item/organ/external/O in character.get_external_organs()) - LAZYCLEARLIST(O.markings) - - for(var/M in body_markings) - var/decl/sprite_accessory/marking/mark_datum = GET_DECL(M) - var/mark_color = "[body_markings[M]]" - - for(var/bodypart in mark_datum.body_parts) - var/obj/item/organ/external/O = GET_EXTERNAL_ORGAN(character, bodypart) - if(O) - LAZYSET(O.markings, M, mark_color) + O.clear_sprite_accessories(skip_update = TRUE) + + for(var/accessory_category in sprite_accessories) + for(var/accessory in sprite_accessories[accessory_category]) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + var/accessory_colour = sprite_accessories[accessory_category][accessory] + for(var/bodypart in accessory_decl.body_parts) + var/obj/item/organ/external/O = GET_EXTERNAL_ORGAN(character, bodypart) + if(O) + O.set_sprite_accessory(accessory, accessory_category, accessory_colour, skip_update = TRUE) if(LAZYLEN(appearance_descriptors)) character.appearance_descriptors = appearance_descriptors.Copy() diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index a5217f66bf6..a0d7a4827cb 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -64,8 +64,8 @@ if(is_husked()) return - set_facial_hairstyle(/decl/sprite_accessory/facial_hair/shaved, skip_update = TRUE) - set_hairstyle(/decl/sprite_accessory/hair/bald, skip_update = FALSE) + SET_FACIAL_HAIR_STYLE(src, /decl/sprite_accessory/facial_hair/shaved, TRUE) + SET_HAIR_STYLE(src, /decl/sprite_accessory/hair/bald, FALSE) mutations.Add(MUTATION_HUSK) for(var/obj/item/organ/external/E in get_external_organs()) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index ac37588b7a9..e62fed67443 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -478,17 +478,6 @@ new_bodytype.create_missing_organs(src, TRUE) // actually rebuild the body apply_bodytype_appearance() force_update_limbs() - - // Check and clear hair. - var/set_hairstyle = get_hairstyle() - var/decl/sprite_accessory/hair/hairstyle = GET_DECL(set_hairstyle) - if(!hairstyle?.accessory_is_available(src, species, new_bodytype)) - set_hairstyle(new_bodytype.default_h_style, skip_update = TRUE) - set_hairstyle = get_facial_hairstyle() - var/decl/sprite_accessory/hair/facialhairstyle = GET_DECL(set_hairstyle) - if(!facialhairstyle?.accessory_is_available(src, species, new_bodytype)) - set_facial_hairstyle(new_bodytype.default_f_style, skip_update = TRUE) - // TODO: check markings. update_hair() update_eyes() return TRUE @@ -628,6 +617,21 @@ default_pixel_y = initial(pixel_y) + root_bodytype.pixel_offset_y default_pixel_z = initial(pixel_z) + root_bodytype.pixel_offset_z + for(var/obj/item/organ/external/E in get_external_organs()) + E.sanitize_sprite_accessories() + + for(var/acc_cat in root_bodytype.default_sprite_accessories) + var/decl/sprite_accessory_category/acc_cat_decl = GET_DECL(acc_cat) + if(!acc_cat_decl.always_apply_defaults) + continue + for(var/accessory in root_bodytype.default_sprite_accessories[acc_cat]) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + var/accessory_colour = root_bodytype.default_sprite_accessories[acc_cat][accessory] + for(var/bodypart in accessory_decl.body_parts) + var/obj/item/organ/external/O = GET_EXTERNAL_ORGAN(src, bodypart) + if(O && O.bodytype == root_bodytype) + O.set_sprite_accessory(accessory, accessory_decl.accessory_category, accessory_colour, skip_update = TRUE) + reset_offsets() /mob/living/carbon/human/proc/update_languages() @@ -998,20 +1002,24 @@ return BULLET_IMPACT_MEAT /mob/living/carbon/human/lose_hair() - if(get_bodytype().set_default_hair(src)) - . = TRUE if(species.handle_additional_hair_loss(src)) . = TRUE for(var/obj/item/organ/external/E in get_external_organs()) - for(var/mark in E.markings) - var/decl/sprite_accessory/marking/mark_datum = GET_DECL(mark) - if(mark_datum.flags & HAIR_LOSS_VULNERABLE) - E.markings -= mark - . = TRUE + if(E.handle_hair_loss()) + . = TRUE if(.) update_body() to_chat(src, SPAN_DANGER("You feel a chill and your skin feels lighter...")) +/obj/item/organ/external/proc/handle_hair_loss() + for(var/accessory_category in _sprite_accessories) + var/list/draw_accessories = _sprite_accessories[accessory_category] + for(var/accessory in draw_accessories) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + if(accessory_decl.accessory_flags & HAIR_LOSS_VULNERABLE) + remove_sprite_accessory(accessory, skip_update = TRUE) + . = TRUE + /mob/living/carbon/human/increaseBodyTemp(value) bodytemperature += value return bodytemperature @@ -1081,14 +1089,10 @@ var/decl/bodytype/root_bodytype = get_bodytype() // root bodytype is set in set_species if(!get_skin_colour()) set_skin_colour(root_bodytype.base_color, skip_update = TRUE) - if(!get_hair_colour()) - set_hair_colour(root_bodytype.base_hair_color, skip_update = TRUE) - if(!get_facial_hair_colour()) - set_facial_hair_colour(root_bodytype.base_hair_color, skip_update = TRUE) if(!get_eye_colour()) set_eye_colour(root_bodytype.base_eye_color, skip_update = TRUE) + root_bodytype.set_default_sprite_accessories(src) - root_bodytype.set_default_hair(src, override_existing = TRUE, defer_update_hair = TRUE) if(!blood_type && length(species?.blood_types)) blood_type = pickweight(species.blood_types) diff --git a/code/modules/mob/living/carbon/human/human_appearance.dm b/code/modules/mob/living/carbon/human/human_appearance.dm index 2f8b796aa5b..728e531b698 100644 --- a/code/modules/mob/living/carbon/human/human_appearance.dm +++ b/code/modules/mob/living/carbon/human/human_appearance.dm @@ -1,51 +1,14 @@ /mob/living/carbon/human - var/_h_style - var/_f_style - var/_hair_colour - var/_facial_hair_colour - var/_eye_colour var/_skin_colour - var/_lip_colour /mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/topic_state/state = global.default_topic_state) var/datum/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist) AC.flags = flags AC.ui_interact(user, state = state) -/mob/living/carbon/human/get_lip_colour() - return _lip_colour - -/mob/living/carbon/human/get_eye_colour() - return _eye_colour - /mob/living/carbon/human/get_skin_colour() return _skin_colour -/mob/living/carbon/human/get_hairstyle() - return _h_style - -/mob/living/carbon/human/get_hair_colour() - return _hair_colour - -/mob/living/carbon/human/get_facial_hairstyle() - return _f_style - -/mob/living/carbon/human/get_facial_hair_colour() - return _facial_hair_colour - -/mob/living/carbon/human/set_lip_colour(var/new_color, var/skip_update = FALSE) - if((. = ..())) - _lip_colour = new_color - if(!skip_update) - update_body() - -/mob/living/carbon/human/set_eye_colour(var/new_color, var/skip_update = FALSE) - if((. = ..())) - _eye_colour = new_color - if(!skip_update) - update_eyes() - update_body() - /mob/living/carbon/human/set_skin_colour(var/new_color, var/skip_update = FALSE) if((. = ..())) _skin_colour = new_color @@ -53,30 +16,6 @@ force_update_limbs() update_body() -/mob/living/carbon/human/set_hair_colour(var/new_color, var/skip_update = FALSE) - if((. = ..())) - _hair_colour = new_color - if(!skip_update) - update_hair() - -/mob/living/carbon/human/set_hairstyle(var/new_hairstyle, var/skip_update = FALSE) - if((. = ..())) - _h_style = new_hairstyle - if(!skip_update) - update_hair() - -/mob/living/carbon/human/set_facial_hair_colour(var/new_color, var/skip_update = FALSE) - if((. = ..())) - _facial_hair_colour = new_color - if(!skip_update) - update_hair() - -/mob/living/carbon/human/set_facial_hairstyle(var/new_facial_hairstyle, var/skip_update = FALSE) - if((. = ..())) - _f_style = new_facial_hairstyle - if(!skip_update) - update_hair() - /mob/living/carbon/human/proc/change_species(var/new_species, var/new_bodytype = null) if(!new_species) return @@ -121,19 +60,24 @@ set_gender(pronouns.name, TRUE) /mob/living/carbon/human/proc/reset_hair() - var/list/valid_hairstyles = get_valid_hairstyle_types() + var/decl/bodytype/root_bodytype = get_bodytype() + var/list/valid_hairstyles = species?.get_available_accessories(root_bodytype, SAC_HAIR) if(length(valid_hairstyles)) - set_hairstyle(pick(valid_hairstyles), skip_update = TRUE) + SET_HAIR_STYLE(src, pick(valid_hairstyles), TRUE) else //this shouldn't happen - set_hairstyle(get_bodytype()?.default_h_style || /decl/sprite_accessory/hair/bald, skip_update = TRUE) + var/new_hair = LAZYACCESS(root_bodytype?.default_sprite_accessories, SAC_HAIR) || /decl/sprite_accessory/hair/bald + if(new_hair) + SET_HAIR_STYLE(src, new_hair, TRUE) - var/list/valid_facial_hairstyles = get_valid_facial_hairstyle_types() + var/list/valid_facial_hairstyles = species?.get_available_accessories(root_bodytype, SAC_FACIAL_HAIR) if(length(valid_facial_hairstyles)) - set_facial_hairstyle(pick(valid_facial_hairstyles), skip_update = TRUE) + SET_FACIAL_HAIR_STYLE(src, pick(valid_facial_hairstyles), TRUE) else //this shouldn't happen - set_facial_hairstyle(get_bodytype()?.default_f_style || /decl/sprite_accessory/facial_hair/shaved, skip_update = TRUE) + var/new_facial_hair = LAZYACCESS(root_bodytype?.default_sprite_accessories, SAC_FACIAL_HAIR) || /decl/sprite_accessory/facial_hair/shaved + if(new_facial_hair) + SET_FACIAL_HAIR_STYLE(src, new_facial_hair, TRUE) update_hair() @@ -168,12 +112,6 @@ return valid_species -/mob/living/carbon/human/proc/get_valid_hairstyle_types() - return species.get_hair_style_types(get_bodytype()) - -/mob/living/carbon/human/proc/get_valid_facial_hairstyle_types() - return species.get_facial_hair_style_types(get_bodytype()) - /mob/living/carbon/human/proc/force_update_limbs() for(var/obj/item/organ/external/O in get_external_organs()) O.sync_colour_to_human(src) diff --git a/code/modules/mob/living/carbon/human/human_appearance_head.dm b/code/modules/mob/living/carbon/human/human_appearance_head.dm new file mode 100644 index 00000000000..d60fc877013 --- /dev/null +++ b/code/modules/mob/living/carbon/human/human_appearance_head.dm @@ -0,0 +1,13 @@ +/mob/living/carbon/human + var/_eye_colour + +// Eyes! TODO, make these a marking. +/mob/living/carbon/human/get_eye_colour() + return _eye_colour + +/mob/living/carbon/human/set_eye_colour(var/new_color, var/skip_update = FALSE) + if((. = ..())) + _eye_colour = new_color + if(!skip_update) + update_eyes() + update_body() diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index d57fc319496..2a738a00112 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -6,8 +6,6 @@ var/damage_multiplier = 1 //multiplies melee combat damage - var/lip_color = null //no lipstick by default- arguably misleading, as it could be used for general makeup - var/list/worn_underwear = list() var/datum/backpack_setup/backpack_setup diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 2a062c62fe9..b0c922c386c 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -20,10 +20,10 @@ to_chat(src, SPAN_WARNING("You can't mess with your hair right now!")) return - var/hairstyle = get_hairstyle() + var/hairstyle = GET_HAIR_STYLE(src) if(hairstyle) var/decl/sprite_accessory/hair/hair_style = GET_DECL(hairstyle) - if(!(hair_style.flags & HAIR_TIEABLE)) + if(!(hair_style.accessory_flags & HAIR_TIEABLE)) to_chat(src, SPAN_WARNING("Your hair isn't long enough to tie.")) return @@ -32,7 +32,7 @@ var/list/hairstyle_instances = list() for(var/hair_type in valid_hairstyles) var/decl/sprite_accessory/hair/test = valid_hairstyles[hair_type] - if(test.flags & HAIR_TIEABLE) + if(test.accessory_flags & HAIR_TIEABLE) hairstyle_instances += test var/decl/selected_decl = input("Select a new hairstyle", "Your hairstyle", hair_style) as null|anything in hairstyle_instances if(selected_decl) @@ -41,8 +41,7 @@ to_chat(src, SPAN_WARNING("You can't mess with your hair right now!")) return if(selected_type && hairstyle != selected_type) - set_hairstyle(selected_type) - try_refresh_visible_overlays() + SET_HAIR_STYLE(src, selected_type, FALSE) visible_message(SPAN_NOTICE("\The [src] pauses a moment to style their hair.")) else to_chat(src, SPAN_NOTICE("You're already using that style.")) diff --git a/code/modules/mob/living/carbon/human/human_verbs.dm b/code/modules/mob/living/carbon/human/human_verbs.dm index f83e9512aee..183b02f5fcc 100644 --- a/code/modules/mob/living/carbon/human/human_verbs.dm +++ b/code/modules/mob/living/carbon/human/human_verbs.dm @@ -11,13 +11,13 @@ src.verbs -= /mob/living/carbon/human/proc/morph return - var/new_facial = input("Please select facial hair color.", "Character Generation", get_facial_hair_colour()) as color + var/new_facial = input("Please select facial hair color.", "Character Generation", GET_FACIAL_HAIR_COLOUR(src)) as color if(new_facial) - set_facial_hair_colour(new_facial, skip_update = TRUE) + SET_FACIAL_HAIR_COLOUR(src, new_facial, TRUE) - var/new_hair = input("Please select hair color.", "Character Generation", get_hair_colour()) as color + var/new_hair = input("Please select hair color.", "Character Generation", GET_HAIR_COLOUR(src)) as color if(new_hair) - set_hair_colour(new_hair, skip_update = TRUE) + SET_HAIR_COLOUR(src, new_hair, TRUE) var/new_eyes = input("Please select eye color.", "Character Generation", get_eye_colour()) as color if(new_eyes) @@ -38,11 +38,11 @@ for(var/x in all_hairs) hairs += all_hairs[x] - var/decl/new_style = input("Please select hair style", "Character Generation",get_hairstyle()) as null|anything in hairs + var/decl/new_style = input("Please select hair style", "Character Generation", GET_HAIR_STYLE(src)) as null|anything in hairs // if new style selected (not cancel) if(new_style) - set_hairstyle(new_style.type, skip_update = TRUE) + SET_HAIR_STYLE(src, new_style.type, TRUE) // facial hair var/list/all_fhairs = decls_repository.get_decls_of_subtype(/decl/sprite_accessory/facial_hair) @@ -51,10 +51,10 @@ for(var/x in all_fhairs) fhairs += all_fhairs[x] - new_style = input("Please select facial style", "Character Generation", get_facial_hairstyle()) as null|anything in fhairs + new_style = input("Please select facial style", "Character Generation", GET_FACIAL_HAIR_STYLE(src)) as null|anything in fhairs if(new_style) - set_facial_hairstyle(new_style.type, skip_update = TRUE) + SET_FACIAL_HAIR_STYLE(src, new_style.type, TRUE) var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female", "Neutral") if (new_gender) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index b0f8727ff59..012623b6aee 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -317,7 +317,8 @@ Please contact me on #coderbus IRC. ~Carn x /mob/living/carbon/human/update_hair(var/update_icons=1) var/obj/item/organ/external/head/head_organ = get_organ(BP_HEAD, /obj/item/organ/external/head) - set_current_mob_overlay(HO_HAIR_LAYER, (istype(head_organ) ? head_organ.get_mob_overlays() : null), update_icons) + var/list/new_accessories = head_organ?.get_mob_overlays() + set_current_mob_overlay(HO_HAIR_LAYER, new_accessories, update_icons) /mob/living/carbon/human/proc/update_skin(var/update_icons=1) // todo: make this use bodytype @@ -386,7 +387,7 @@ Please contact me on #coderbus IRC. ~Carn x return // No tail data! // These values may be null and are generally optional. - var/hair_colour = get_hair_colour() + var/hair_colour = GET_HAIR_COLOUR(src) var/skin_colour = get_skin_colour() var/tail_hair = tail_organ.get_tail_hair() var/tail_blend = tail_organ.get_tail_blend() diff --git a/code/modules/mob/living/living_appearance.dm b/code/modules/mob/living/living_appearance.dm index 359cb835ccf..9a1d54672b2 100644 --- a/code/modules/mob/living/living_appearance.dm +++ b/code/modules/mob/living/living_appearance.dm @@ -17,48 +17,41 @@ add_overlay(A) try_refresh_visible_overlays() -/mob/living/proc/get_skin_colour() - return - -/mob/living/proc/get_eye_colour() - return +/mob/living/proc/set_organ_sprite_accessory(var/accessory_type, var/accessory_category, var/accessory_color, var/organ_tag, var/skip_update = FALSE) + if(!accessory_category || !organ_tag) + return + var/obj/item/organ/external/organ = organ_tag && GET_EXTERNAL_ORGAN(src, organ_tag) + if(!organ) + return + if(!accessory_type) + accessory_type = organ.get_sprite_accessory_by_category(accessory_category) + if(accessory_type) + return organ.set_sprite_accessory(accessory_type, accessory_category, accessory_color, skip_update) + +/mob/living/proc/get_organ_sprite_accessory(var/accessory_type, var/organ_tag) + var/obj/item/organ/external/organ = organ_tag && GET_EXTERNAL_ORGAN(src, organ_tag) + return organ?.get_sprite_accessory_value(accessory_type) + +/mob/living/proc/get_organ_sprite_accessory_by_category(var/accessory_category, var/organ_tag) + var/obj/item/organ/external/organ = organ_tag && GET_EXTERNAL_ORGAN(src, organ_tag) + return organ?.get_sprite_accessory_by_category(accessory_category) + +/mob/living/proc/set_organ_sprite_accessory_by_category(var/accessory_type, var/accessory_category, var/accessory_color, var/preserve_colour = TRUE, var/preserve_type = TRUE, var/organ_tag, var/skip_update = FALSE) + var/obj/item/organ/external/organ = organ_tag && GET_EXTERNAL_ORGAN(src, organ_tag) + return organ?.set_sprite_accessory_by_category(accessory_type, accessory_category, accessory_color, preserve_colour, preserve_type, skip_update) -/mob/living/proc/get_lip_colour() - return - -/mob/living/proc/get_hairstyle() - return - -/mob/living/proc/get_facial_hairstyle() +/mob/living/proc/get_skin_colour() return -/mob/living/proc/get_hair_colour() - return +/mob/living/proc/set_skin_colour(var/new_color, var/skip_update = FALSE) + return get_skin_colour() != new_color -/mob/living/proc/get_facial_hair_colour() +/mob/living/proc/get_eye_colour() return -/mob/living/proc/set_skin_colour(var/new_color) - return get_skin_colour() != new_color - -/mob/living/proc/set_eye_colour(var/new_color) +/mob/living/proc/set_eye_colour(var/new_color, var/skip_update = FALSE) return get_eye_colour() != new_color -/mob/living/proc/set_lip_colour(var/new_color) - return get_lip_colour() != new_color - -/mob/living/proc/set_facial_hair_colour(var/new_color, var/skip_update = FALSE) - return get_facial_hair_colour() != new_color - -/mob/living/proc/set_hair_colour(var/new_color, var/skip_update = FALSE) - return get_hair_colour() != new_color - -/mob/living/proc/set_hairstyle(var/new_hairstyle) - return new_hairstyle && get_hairstyle() != new_hairstyle && ispath(new_hairstyle, /decl/sprite_accessory/hair) - -/mob/living/proc/set_facial_hairstyle(var/new_facial_hairstyle) - return new_facial_hairstyle && get_facial_hairstyle() != new_facial_hairstyle && ispath(new_facial_hairstyle, /decl/sprite_accessory/facial_hair) - /mob/living/get_all_current_mob_overlays() return mob_overlays diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 5445b9c23dc..f7f0ced3a96 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -1,22 +1,24 @@ -/datum/preferences/proc/random_hair_style() - var/decl/species/mob_species = get_species_decl() - var/list/valid_styles = mob_species?.get_hair_style_types(get_bodytype_decl()) - return length(valid_styles) ? pick(valid_styles) : /decl/sprite_accessory/hair/bald - -/datum/preferences/proc/random_facial_hair_style() - var/decl/species/mob_species = get_species_decl() - var/list/valid_styles = mob_species?.get_facial_hair_style_types(get_bodytype_decl()) - return length(valid_styles) ? pick(valid_styles) : /decl/sprite_accessory/facial_hair/shaved - /datum/preferences/proc/randomize_appearance_and_body_for(var/mob/living/carbon/human/H) + if(!H) + H = client?.mob + var/decl/species/current_species = get_species_decl() var/decl/bodytype/current_bodytype = current_species.get_bodytype_by_name(bodytype) || current_species.default_bodytype var/decl/pronouns/pronouns = pick(current_species.available_pronouns) gender = pronouns.name - h_style = random_hair_style() - f_style = random_facial_hair_style() + for(var/acc_cat in sprite_accessories) + var/decl/sprite_accessory_category/accessory_category_decl = GET_DECL(acc_cat) + if(accessory_category_decl.single_selection) + var/list/available_styles = get_usable_sprite_accessories(H, current_species, current_bodytype, acc_cat, null) + if(length(available_styles)) + sprite_accessories[acc_cat][1] = pick(available_styles) + sprite_accessories[acc_cat][sprite_accessories[acc_cat][1]] = get_random_colour() + continue + for(var/accessory in sprite_accessories[acc_cat]) + sprite_accessories[acc_cat][accessory] = get_random_colour() + if(bodytype) if(current_bodytype.appearance_flags & HAS_A_SKIN_TONE) skin_tone = current_bodytype.get_random_skin_tone() || skin_tone @@ -24,9 +26,6 @@ eye_colour = current_bodytype.get_random_eye_color() if(current_bodytype.appearance_flags & HAS_SKIN_COLOR) skin_colour = current_bodytype.get_random_skin_color() - if(current_bodytype.appearance_flags & HAS_HAIR_COLOR) - hair_colour = current_bodytype.get_random_hair_color() - facial_hair_colour = prob(75) ? hair_colour : current_bodytype.get_random_facial_hair_color() if(all_underwear) all_underwear.Cut() @@ -35,9 +34,6 @@ var/datum/category_item/underwear/WRI = pick(WRC.items) all_underwear[WRC.name] = WRI.name - for(var/M in body_markings) - body_markings[M] = get_random_colour() - for(var/entry in current_species.appearance_descriptors) var/datum/appearance_descriptor/descriptor = current_species.appearance_descriptors[entry] if(istype(descriptor)) diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index a6772cb01b9..926fe34acf2 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -48,25 +48,25 @@ if(href_list["hair"]) var/decl/sprite_accessory/hair = locate(href_list["hair"]) - if(can_change(APPEARANCE_HAIR) && istype(hair) && (hair.type in owner.get_valid_hairstyle_types()) && owner.set_hairstyle(hair.type)) + if(can_change(APPEARANCE_HAIR) && istype(hair) && (hair.type in owner.get_species()?.get_available_accessory_types(owner.get_bodytype(), SAC_HAIR)) && SET_HAIR_STYLE(owner, hair.type, FALSE)) update_dna() return TRUE if(href_list["hair_color"] && can_change(APPEARANCE_HAIR_COLOR)) - var/new_hair = input("Please select hair color.", "Hair Color", owner.get_hair_colour()) as color|null - if(new_hair && can_still_topic(state) && owner.set_hair_colour(new_hair)) + var/new_hair = input("Please select hair color.", "Hair Color", GET_HAIR_COLOUR(owner)) as color|null + if(new_hair && can_still_topic(state) && SET_HAIR_COLOUR(owner, new_hair, FALSE)) update_dna() return TRUE if(href_list["facial_hair"]) var/decl/sprite_accessory/facial_hair = locate(href_list["facial_hair"]) - if(can_change(APPEARANCE_FACIAL_HAIR) && istype(facial_hair) && (facial_hair.type in owner.get_valid_facial_hairstyle_types()) && owner.set_facial_hairstyle(facial_hair.type)) + if(can_change(APPEARANCE_FACIAL_HAIR) && istype(facial_hair) && (facial_hair.type in owner.get_species()?.get_available_accessory_types(owner.get_bodytype(), SAC_FACIAL_HAIR)) && SET_FACIAL_HAIR_STYLE(owner, facial_hair.type, FALSE)) update_dna() return TRUE if(href_list["facial_hair_color"] && can_change(APPEARANCE_FACIAL_HAIR_COLOR)) - var/new_facial = input("Please select facial hair color.", "Facial Hair Color", owner.get_facial_hair_colour()) as color|null - if(new_facial && can_still_topic(state) && owner.set_facial_hair_colour(new_facial)) + var/new_facial = input("Please select facial hair color.", "Facial Hair Color", GET_FACIAL_HAIR_COLOUR(owner)) as color|null + if(new_facial && can_still_topic(state) && SET_FACIAL_HAIR_COLOUR(owner, new_facial, FALSE)) update_dna() return TRUE @@ -115,22 +115,22 @@ if(data["change_hair"]) var/hair_styles[0] - for(var/hair_style in owner.get_valid_hairstyle_types()) + for(var/hair_style in owner.get_species()?.get_available_accessory_types(owner.get_bodytype(), SAC_HAIR)) var/decl/sprite_accessory/hair_decl = GET_DECL(hair_style) hair_styles[++hair_styles.len] = list("hairstyle" = hair_decl.name, "ref" = "\ref[hair_decl]") data["hair_styles"] = hair_styles - var/hairstyle = owner.get_hairstyle() + var/hairstyle = GET_HAIR_STYLE(owner) var/decl/sprite_accessory/hair = GET_DECL(hairstyle) data["hair_style"] = hair.name data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) if(data["change_facial_hair"]) var/facial_hair_styles[0] - for(var/facial_hair_style in owner.get_valid_facial_hairstyle_types()) + for(var/facial_hair_style in owner.get_species()?.get_available_accessory_types(owner.get_bodytype(), SAC_FACIAL_HAIR)) var/decl/sprite_accessory/facial_hair_decl = GET_DECL(facial_hair_style) facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_decl.name, "ref" = "\ref[facial_hair_decl]") data["facial_hair_styles"] = facial_hair_styles - var/facial_hairstyle = owner.get_facial_hairstyle() + var/facial_hairstyle = GET_FACIAL_HAIR_STYLE(owner) var/decl/sprite_accessory/facial_hair = GET_DECL(facial_hairstyle) data["facial_hair_style"] = facial_hair.name diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 89abfd941d8..8c86779a290 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -36,10 +36,12 @@ var/skin_colour // skin colour var/skin_blend = ICON_ADD // How the skin colour is applied. var/hair_colour // hair colour - var/list/markings // Markings (body_markings) to apply to the icon var/render_alpha = 255 var/skip_body_icon_draw = FALSE // Set to true to skip including this organ on the human body sprite. + /// Sprite accessories like hair and markings to apply to the organ icon and owner. + VAR_PRIVATE/list/_sprite_accessories + // Wound and structural data. var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often var/list/wounds // wound datum list. diff --git a/code/modules/organs/external/_external_icons.dm b/code/modules/organs/external/_external_icons.dm index aa77c6e51fc..c8dd056c9cb 100644 --- a/code/modules/organs/external/_external_icons.dm +++ b/code/modules/organs/external/_external_icons.dm @@ -19,7 +19,6 @@ var/global/list/limb_icon_cache = list() _icon_cache_key = null skin_tone = null skin_colour = null - hair_colour = human.get_hair_colour() // This used to do a bodytype set but that was *really really bad.* Things that need that should do it themselves. skin_blend = bodytype.limb_blend if(!isnull(human.skin_tone) && bodytype?.appearance_flags & HAS_A_SKIN_TONE) @@ -31,7 +30,6 @@ var/global/list/limb_icon_cache = list() _icon_cache_key = null skin_tone = null skin_colour = null - hair_colour = rgb(dna.GetUIValue(DNA_UI_HAIR_R),dna.GetUIValue(DNA_UI_HAIR_G),dna.GetUIValue(DNA_UI_HAIR_B)) if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && (bodytype.appearance_flags & HAS_A_SKIN_TONE)) skin_tone = dna.GetUIValue(DNA_UI_SKIN_TONE) if(bodytype.appearance_flags & HAS_SKIN_COLOR) @@ -73,33 +71,160 @@ var/global/list/organ_icon_cache = list() if((bodytype.appearance_flags & HAS_SKIN_COLOR) && skin_colour) ret.Blend(skin_colour, skin_blend) - //Body markings. - for(var/M in markings) - var/decl/sprite_accessory/marking/mark_style = resolve_accessory_to_decl(M) - if(mark_style && !mark_style.sprite_overlay_layer) - ret.Blend(mark_style.get_cached_accessory_icon(src, markings[M]), mark_style.layer_blend) + // Body markings, hair, lips, etc. + for(var/accessory_category in _sprite_accessories) + var/list/draw_accessories = _sprite_accessories[accessory_category] + for(var/accessory in draw_accessories) + var/decl/sprite_accessory/accessory_decl = resolve_accessory_to_decl(accessory) + if(istype(accessory_decl) && !accessory_decl.sprite_overlay_layer) + ret.Blend(accessory_decl.get_cached_accessory_icon(src, draw_accessories[accessory] || COLOR_WHITE), accessory_decl.layer_blend) if(render_alpha < 255) ret += rgb(,,,render_alpha) global.organ_icon_cache[_icon_cache_key] = ret return ret /obj/item/organ/external/proc/get_mob_overlays() - for(var/M in markings) - var/decl/sprite_accessory/marking/mark_style = resolve_accessory_to_decl(M) - if(mark_style?.sprite_overlay_layer) - var/image/mark_image = image(mark_style.get_cached_accessory_icon(src, markings[M])) - mark_image.layer = mark_style.sprite_overlay_layer - LAZYADD(., mark_image) + for(var/accessory_category in _sprite_accessories) + var/list/draw_accessories = _sprite_accessories[accessory_category] + for(var/accessory in draw_accessories) + var/decl/sprite_accessory/accessory_decl = resolve_accessory_to_decl(accessory) + if(istype(accessory_decl) && !isnull(accessory_decl.sprite_overlay_layer)) + var/image/accessory_image = image(accessory_decl.get_cached_accessory_icon(src, draw_accessories[accessory] || COLOR_WHITE)) + if(accessory_decl.sprite_overlay_layer != FLOAT_LAYER) + accessory_image.layer = accessory_decl.sprite_overlay_layer + if(accessory_decl.layer_blend != ICON_OVERLAY) + accessory_image.blend_mode = iconMode2blendMode(accessory_decl.layer_blend) + LAZYADD(., accessory_image) /obj/item/organ/external/proc/get_icon_cache_key_components() . = list("[icon_state]_[species.name]_[bodytype.name]_[render_alpha]_[icon]") - for(var/M in markings) - var/decl/sprite_accessory/marking/mark_style = GET_DECL(M) - if(!mark_style.sprite_overlay_layer) - . += "_[M][markings[M]]" if(status & ORGAN_DEAD) . += "_dead" . += "_tone_[skin_tone]_color_[skin_colour]_[skin_blend]" + for(var/accessory_category in _sprite_accessories) + var/list/draw_accessories = _sprite_accessories[accessory_category] + for(var/accessory in draw_accessories) + var/decl/sprite_accessory/accessory_decl = resolve_accessory_to_decl(accessory) + if(istype(accessory_decl) && !accessory_decl.sprite_overlay_layer) + . += "_[accessory]_[draw_accessories[accessory]]" + +/obj/item/organ/external/proc/clear_sprite_accessories(var/skip_update = FALSE) + if(!length(_sprite_accessories)) + return + LAZYCLEARLIST(_sprite_accessories) + if(!skip_update) + if(owner) + owner.update_body() + update_icon() + +/obj/item/organ/external/proc/get_sprite_accessories_by_category(var/accessory_category) + return LAZYACCESS(_sprite_accessories, accessory_category) + +/obj/item/organ/external/proc/get_sprite_accessory_by_category(var/accessory_category) + var/list/accessories = get_sprite_accessories_by_category(accessory_category) + if(length(accessories)) + return accessories[1] + +/obj/item/organ/external/proc/get_sprite_accessory_value(var/accessory_type) + var/decl/sprite_accessory/accessory = GET_DECL(accessory_type) + var/list/accessories = istype(accessory) && LAZYACCESS(_sprite_accessories, accessory.accessory_category) + if(accessories) + return accessories[accessory_type] + +/obj/item/organ/external/proc/set_sprite_accessory(var/accessory_type, var/accessory_category, var/accessory_color, var/skip_update = FALSE) + + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory_type) + if(!accessory_category) + if(!accessory_decl) + return + accessory_category = accessory_decl.accessory_category + + var/list/accessories = LAZYACCESS(_sprite_accessories, accessory_category) + if(!accessories) + accessories = list() + LAZYSET(_sprite_accessories, accessory_category, accessories) + + if(!accessory_type) + var/decl/sprite_accessory_category/accessory_cat = GET_DECL(accessory_category) + accessory_type = accessory_cat?.default_accessory + if(!accessory_type) + return + accessory_decl = GET_DECL(accessory_type) + + if(accessory_color) + if(!accessory_decl.accessory_is_available(owner, species, bodytype)) + return + if(LAZYACCESS(accessories, accessory_type) == accessory_color) + return + LAZYSET(accessories, accessory_type, accessory_color) + else + if(!(accessory_type in accessories)) + return + remove_sprite_accessory(accessory_type, TRUE) + + if(!skip_update) + if(owner && accessory_type) + var/decl/sprite_accessory/refresh_accessory = GET_DECL(accessory_type) + if(refresh_accessory) + refresh_accessory.refresh_mob(owner) + update_icon() + +/obj/item/organ/external/proc/get_heritable_sprite_accessories() + for(var/accessory_category in _sprite_accessories) + var/list/draw_accessories = _sprite_accessories[accessory_category] + for(var/accessory in draw_accessories) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + if(accessory_decl?.is_heritable) + LAZYADD(., accessory) + +/obj/item/organ/external/proc/set_sprite_accessory_by_category(accessory_type, accessory_category, accessory_color, preserve_colour = TRUE, preserve_type = TRUE, skip_update) + if(!accessory_category) + return + if(istype(accessory_type, /decl/sprite_accessory)) + var/decl/accessory_decl = accessory_type + accessory_type = accessory_decl.type + + // If there is a pre-existing sprite accessory to replace, we may want to keep the old colour value. + var/do_update_if_returning = FALSE + var/replacing_type = get_sprite_accessory_by_category(accessory_category) + if(replacing_type) + + if(preserve_colour && !accessory_color) + accessory_color = get_sprite_accessory_value(replacing_type) + + // We may only be setting colour, in which case we don't bother with a removal. + if(preserve_type && !accessory_type) + accessory_type = replacing_type + else + remove_sprite_accessory(replacing_type, TRUE) + + // We have already done our removal above and have nothing further to set below. + if(!accessory_color && !accessory_type) + if(!skip_update) + if(owner) + var/decl/sprite_accessory/refresh_accessory = GET_DECL(replacing_type || accessory_category) + if(refresh_accessory) + refresh_accessory.refresh_mob(owner) + update_icon() + return do_update_if_returning + + // We need to now set a replacement accessory type down the chain. + return set_sprite_accessory(accessory_type, accessory_category, accessory_color, skip_update) + +/obj/item/organ/external/proc/remove_sprite_accessory(var/accessory_type, var/skip_update = FALSE) + if(!accessory_type) + return + var/decl/sprite_accessory/removing_accessory = GET_DECL(accessory_type) + var/list/removing = LAZYACCESS(_sprite_accessories, removing_accessory.accessory_category) + if(!LAZYLEN(removing)) + return + LAZYREMOVE(removing, accessory_type) + if(!length(removing)) + LAZYREMOVE(_sprite_accessories, removing_accessory.accessory_category) + if(!skip_update) + if(owner && removing_accessory) + removing_accessory.refresh_mob(owner) + update_icon() /obj/item/organ/external/on_update_icon() . = ..() @@ -108,6 +233,7 @@ var/global/list/organ_icon_cache = list() update_limb_icon_file() if(icon_state != organ_tag) icon_state = organ_tag + _icon_cache_key = jointext(get_icon_cache_key_components(), null) var/icon/mob_icon = global.organ_icon_cache[_icon_cache_key] || generate_mob_icon() if(icon != mob_icon) @@ -183,9 +309,21 @@ var/global/list/robot_hud_colours = list("#ffffff","#cccccc","#aaaaaa","#888888" if(ispath(accessory_style)) accessory_style = GET_DECL(accessory_style) // Check if this style is permitted for this species, period. - if(!accessory_style.accessory_is_available(owner, species, bodytype)) + if(!istype(accessory_style) || !accessory_style?.accessory_is_available(owner, species, bodytype)) return null // Check if we are concealed (long hair under a hat for example). if(accessory_style.is_hidden(src)) return accessory_style.get_hidden_substitute() return accessory_style + +/obj/item/organ/external/proc/sanitize_sprite_accessories(var/skip_update = FALSE) + for(var/acc_cat in _sprite_accessories) + for(var/accessory in _sprite_accessories[acc_cat]) + var/decl/sprite_accessory/accessory_style = GET_DECL(accessory) + if(!istype(accessory_style) || !accessory_style?.accessory_is_available(owner, species, bodytype)) + _sprite_accessories[acc_cat] -= accessory + . = TRUE + if(.) + _icon_cache_key = null + if(!skip_update) + update_icon() diff --git a/code/modules/organs/external/head.dm b/code/modules/organs/external/head.dm index 9ea8af56647..b8c6b3532c7 100644 --- a/code/modules/organs/external/head.dm +++ b/code/modules/organs/external/head.dm @@ -13,12 +13,10 @@ encased = "skull" artery_name = "carotid artery" cavity_name = "cranial" - limb_flags = ORGAN_FLAG_CAN_AMPUTATE | ORGAN_FLAG_HEALS_OVERKILL | ORGAN_FLAG_CAN_BREAK | ORGAN_FLAG_CAN_DISLOCATE var/glowing_eyes = FALSE var/can_intake_reagents = TRUE - var/has_lips = TRUE var/forehead_graffiti var/graffiti_style @@ -77,7 +75,6 @@ /obj/item/organ/external/head/set_bodytype(decl/bodytype/new_bodytype, override_material = null, apply_to_internal_organs = TRUE) . = ..() - has_lips = (bodytype.appearance_flags & HAS_LIPS) can_intake_reagents = !(bodytype.body_flags & BODY_FLAG_NO_EAT) /obj/item/organ/external/head/take_external_damage(brute, burn, damage_flags, used_weapon, override_droplimb) @@ -97,29 +94,13 @@ /obj/item/organ/external/head/get_icon_cache_key_components() . = ..() - if(bodytype.has_eyes) - . += "_eyes[get_eyes_organ()?.eye_colour][bodytype.eye_icon]" - if(bodytype.appearance_flags & HAS_LIPS) - var/lip_icon = bodytype.get_lip_icon(owner) - if(lip_icon) - . += "_lips[lip_icon][owner?.lip_color || "skip"]" + . += "_eyes_[bodytype.eye_icon || "none"]_[get_eyes_organ()?.eye_colour || "none"]" /obj/item/organ/external/head/generate_mob_icon() var/icon/ret = ..() - // Eye icon. - if(bodytype.has_eyes) - var/icon/eyes_icon = get_eyes_organ()?.get_onhead_icon() - if(eyes_icon) - ret.Blend(eyes_icon, ICON_OVERLAY) - // Lip icon. - if(owner && (bodytype.appearance_flags & HAS_LIPS)) - var/lip_icon = bodytype.get_lip_icon(owner) - if(lip_icon) - var/lip_color = owner?.lip_color - if(lip_color) - var/icon/lip_appearance = new/icon(lip_icon, "lipstick_s") - lip_appearance.Blend(lip_color || COLOR_BLACK, ICON_MULTIPLY) - ret.Blend(lip_appearance, ICON_OVERLAY) + var/icon/eyes_icon = get_eyes_organ()?.get_onhead_icon() + if(eyes_icon) + ret.Blend(eyes_icon, ICON_OVERLAY) return ret /obj/item/organ/external/head/get_mob_overlays() @@ -127,15 +108,3 @@ var/image/eye_glow = get_organ_eyes_overlay() if(eye_glow) LAZYADD(., eye_glow) - if(!owner) - return - var/facial_hairstyle = owner.get_facial_hairstyle() - if(facial_hairstyle) - var/decl/sprite_accessory/facial_hair_style = resolve_accessory_to_decl(facial_hairstyle) - if(facial_hair_style?.accessory_is_available(owner, species, bodytype)) - LAZYADD(., image(facial_hair_style.get_cached_accessory_icon(src, owner.get_facial_hair_colour()))) - var/hairstyle = owner.get_hairstyle() - if(hairstyle) - var/decl/sprite_accessory/hair/hair_style = resolve_accessory_to_decl(hairstyle) - if(hair_style?.accessory_is_available(owner, species, bodytype)) - LAZYADD(., image(hair_style.get_cached_accessory_icon(src, owner.get_hair_colour()))) diff --git a/code/modules/organs/external/insectoid.dm b/code/modules/organs/external/insectoid.dm index 019c92f3eb7..29588607cc1 100644 --- a/code/modules/organs/external/insectoid.dm +++ b/code/modules/organs/external/insectoid.dm @@ -39,7 +39,6 @@ /obj/item/organ/external/head/insectoid name = "head" - has_lips = 0 encased = "carapace" /obj/item/organ/external/chest/insectoid diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 7aef3836cce..9d3c565767d 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -153,7 +153,8 @@ return TRUE /obj/item/paper/attack(mob/living/carbon/M, mob/living/carbon/user) - if(user.get_target_zone() == BP_EYES) + var/target_zone = user.get_target_zone() + if(target_zone == BP_EYES) user.visible_message( SPAN_NOTICE("You show the paper to [M]."), SPAN_NOTICE("[user] holds up a paper and shows it to [M].") @@ -161,22 +162,23 @@ M.examinate(src) return TRUE - if(user.get_target_zone() == BP_MOUTH && M.get_lip_colour()) + target_zone = check_zone(target_zone) + if(M.get_organ_sprite_accessory_by_category(SAC_COSMETICS, target_zone)) var/mob/living/carbon/human/H = M if(H == user) - to_chat(user, SPAN_NOTICE("You wipe off the lipstick with [src].")) - H.set_lip_colour() + to_chat(user, SPAN_NOTICE("You wipe off the makeup with [src].")) + H.set_organ_sprite_accessory_by_category(null, SAC_COSMETICS, null, FALSE, FALSE, target_zone, FALSE) return TRUE user.visible_message( - SPAN_NOTICE("\The [user] begins to wipe \the [H]'s lipstick off with \the [src]."), - SPAN_NOTICE("You begin to wipe off [H]'s lipstick.") + SPAN_NOTICE("\The [user] begins to wipe \the [H]'s makeup off with \the [src]."), + SPAN_NOTICE("You begin to wipe off [H]'s makeup .") ) if(do_after(user, 10, H) && do_after(H, 10, check_holding = 0)) //user needs to keep their active hand, H does not. user.visible_message( - SPAN_NOTICE("\The [user] wipes \the [H]'s lipstick off with \the [src]."), - SPAN_NOTICE("You wipe off \the [H]'s lipstick.") + SPAN_NOTICE("\The [user] wipes \the [H]'s makeup off with \the [src]."), + SPAN_NOTICE("You wipe off \the [H]'s makeup .") ) - H.set_lip_colour() + H.set_organ_sprite_accessory_by_category(null, SAC_COSMETICS, null, FALSE, FALSE, target_zone, FALSE) return TRUE . = ..() diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index b3b3912ac10..c9615d089c2 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -23,11 +23,20 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/base_external_prosthetics_model = /decl/bodytype/prosthetic/basic_human var/base_internal_prosthetics_model + // A list of customization categories made available in character preferences. + var/list/available_accessory_categories = list( + SAC_HAIR, + SAC_FACIAL_HAIR, + SAC_COSMETICS, + SAC_MARKINGS + ) + // Lists of accessory types for modpack modification of accessory restrictions. // These lists are pretty broad and indiscriminate in application, don't use // them for fine detail restriction/allowing if you can avoid it. var/list/allow_specific_sprite_accessories var/list/disallow_specific_sprite_accessories + var/list/accessory_styles var/list/blood_types = list( /decl/blood_type/aplus, @@ -43,8 +52,6 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/flesh_color = "#ffc896" // Pink. var/blood_oxy = 1 - var/static/list/hair_styles - var/static/list/facial_hair_styles var/organs_icon //species specific internal organs icons @@ -673,55 +680,27 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/decl/pronouns/G = H.get_pronouns() return SPAN_DANGER("[G.His] face is horribly mangled!\n") -/decl/species/proc/get_hair_style_types(var/decl/bodytype/bodytype) - if(!bodytype) - bodytype = default_bodytype - var/list/hair_styles_by_species = LAZYACCESS(hair_styles, type) - if(!hair_styles_by_species) - hair_styles_by_species = list() - LAZYSET(hair_styles, type, hair_styles_by_species) - var/list/hair_style_by_bodytype = hair_styles_by_species[bodytype] - if(!hair_style_by_bodytype) - hair_style_by_bodytype = list() - LAZYSET(hair_styles_by_species, bodytype, hair_style_by_bodytype) - var/list/all_hairstyles = decls_repository.get_decls_of_subtype(/decl/sprite_accessory/hair) - for(var/hairstyle in all_hairstyles) - var/decl/sprite_accessory/S = all_hairstyles[hairstyle] - if(!S.accessory_is_available(null, src, bodytype)) - continue - ADD_SORTED(hair_style_by_bodytype, hairstyle, /proc/cmp_text_asc) - hair_style_by_bodytype[hairstyle] = S - return hair_style_by_bodytype - -/decl/species/proc/get_hair_styles(var/decl/bodytype/bodytype) +/decl/species/proc/get_available_accessories(var/decl/bodytype/bodytype, accessory_category) . = list() - for(var/hair in get_hair_style_types(bodytype)) - . += GET_DECL(hair) + for(var/accessory in get_available_accessory_types(bodytype, accessory_category)) + . += GET_DECL(accessory) -/decl/species/proc/get_facial_hair_style_types(var/decl/bodytype/bodytype) +/decl/species/proc/get_available_accessory_types(bodytype, accessory_category) if(!bodytype) bodytype = default_bodytype - var/list/facial_hair_styles_by_species = LAZYACCESS(facial_hair_styles, type) - if(!facial_hair_styles_by_species) - facial_hair_styles_by_species = list() - LAZYSET(facial_hair_styles, type, facial_hair_styles_by_species) - var/list/facial_hair_style_by_bodytype = facial_hair_styles_by_species[bodytype] - if(!facial_hair_style_by_bodytype) - facial_hair_style_by_bodytype = list() - LAZYSET(facial_hair_styles_by_species, bodytype, facial_hair_style_by_bodytype) - var/list/all_facial_styles = decls_repository.get_decls_of_subtype(/decl/sprite_accessory/facial_hair) - for(var/facialhairstyle in all_facial_styles) - var/decl/sprite_accessory/S = all_facial_styles[facialhairstyle] - if(!S.accessory_is_available(null, src, bodytype)) + var/list/available_accessories = LAZYACCESS(accessory_styles, accessory_category) + if(!available_accessories) + available_accessories = list() + LAZYSET(accessory_styles, accessory_category, available_accessories) + var/decl/sprite_accessory_category/accessory_category_decl = GET_DECL(accessory_category) + var/list/all_accessories = decls_repository.get_decls_of_subtype(accessory_category_decl.base_accessory_type) + for(var/accessory_style in all_accessories) + var/decl/sprite_accessory/check_accessory = all_accessories[accessory_style] + if(!check_accessory || !check_accessory.accessory_is_available(null, src, bodytype)) continue - ADD_SORTED(facial_hair_style_by_bodytype, facialhairstyle, /proc/cmp_text_asc) - facial_hair_style_by_bodytype[facialhairstyle] = S - return facial_hair_style_by_bodytype - -/decl/species/proc/get_facial_hair_styles(var/decl/bodytype/bodytype) - . = list() - for(var/hair in get_facial_hair_style_types(bodytype)) - . += GET_DECL(hair) + ADD_SORTED(available_accessories, accessory_style, /proc/cmp_text_asc) + available_accessories[accessory_style] = check_accessory + return available_accessories /decl/species/proc/skills_from_age(age) //Converts an age into a skill point allocation modifier. Can be used to give skill point bonuses/penalities not depending on job. switch(age) diff --git a/code/modules/species/species_bodytype.dm b/code/modules/species/species_bodytype.dm index 7697de76c55..823804917cd 100644 --- a/code/modules/species/species_bodytype.dm +++ b/code/modules/species/species_bodytype.dm @@ -6,7 +6,7 @@ var/global/list/bodytypes_by_category = list() var/desc var/icon_base var/icon_deformed - var/lip_icon + var/cosmetics_icon var/bandages_icon var/bodytype_flag = BODY_FLAG_HUMANOID var/bodytype_category = BODYTYPE_OTHER @@ -82,7 +82,6 @@ var/global/list/bodytypes_by_category = list() // Used for initializing prefs/preview var/base_color = COLOR_BLACK var/base_eye_color = COLOR_BLACK - var/base_hair_color = COLOR_BLACK /// Used to initialize organ material var/material = /decl/material/solid/organic/meat @@ -143,10 +142,7 @@ var/global/list/bodytypes_by_category = list() var/vital_organ_failure_death_delay = 25 SECONDS var/mob_size = MOB_SIZE_MEDIUM - var/default_h_style = /decl/sprite_accessory/hair/bald - var/default_f_style = /decl/sprite_accessory/facial_hair/shaved - - var/list/base_markings + var/list/default_sprite_accessories // Darksight handling /// Fractional multiplier (0 to 1) for the base alpha of the darkness overlay. A value of 1 means darkness is completely invisible. @@ -279,14 +275,23 @@ var/global/list/bodytypes_by_category = list() . += "\"[BP_CHEST]\" state not present in icon_deformed" if((appearance_flags & HAS_SKIN_COLOR) && isnull(base_color)) . += "uses skin color but missing base_color" - if((appearance_flags & HAS_HAIR_COLOR) && isnull(base_hair_color)) - . += "uses hair color but missing base_hair_color" if((appearance_flags & HAS_EYE_COLOR) && isnull(base_eye_color)) . += "uses eye color but missing base_eye_color" - if(isnull(default_h_style)) - . += "null default_h_style (use a bald/hairless hairstyle if 'no hair' is intended)" - if(isnull(default_f_style)) - . += "null default_f_style (use a shaved/hairless facial hair style if 'no facial hair' is intended)" + + for(var/accessory_category in default_sprite_accessories) + var/decl/sprite_accessory_category/acc_cat = GET_DECL(accessory_category) + if(!istype(acc_cat)) + . += "invalid sprite accessory category entry: [accessory_category || "null"]" + continue + for(var/accessory in default_sprite_accessories[accessory_category]) + var/decl/sprite_accessory/acc_decl = GET_DECL(accessory) + if(!istype(acc_decl)) + . += "invalid sprite accessory in category [accessory_category]: [accessory || "null"]" + continue + if(acc_decl.accessory_category != acc_cat.type) + . += "accessory category [acc_decl.accessory_category || "null"] does not match [acc_cat.type]" + if(!istype(acc_decl, acc_cat.base_accessory_type)) + . += "accessory type [acc_decl.type] does not align with category base accessory: [acc_cat.base_accessory_type || "null"]" var/list/tail_data = has_limbs[BP_TAIL] if(tail_data) @@ -435,33 +440,26 @@ var/global/list/bodytypes_by_category = list() if(initial(I.parent_organ) == organ.organ_tag) limb.cavity_max_w_class = max(limb.cavity_max_w_class, get_resized_organ_w_class(initial(I.w_class))) -/decl/bodytype/proc/set_default_hair(mob/living/carbon/human/organism, override_existing = TRUE, defer_update_hair = FALSE) - if(!organism.get_hairstyle() || (override_existing && (organism.get_hairstyle() != default_h_style))) - organism.set_hairstyle(default_h_style) - . = TRUE - if(!organism.get_hairstyle() || (override_existing && (organism.get_facial_hairstyle() != default_f_style))) - organism.set_facial_hairstyle(default_f_style) - . = TRUE - if(. && !defer_update_hair) - organism.update_hair() - -/decl/bodytype/proc/customize_preview_mannequin(mob/living/carbon/human/dummy/mannequin/mannequin) - if(length(base_markings)) - for(var/mark_type in base_markings) - var/decl/sprite_accessory/marking/mark_decl = GET_DECL(mark_type) - for(var/bodypart in mark_decl.body_parts) - var/obj/item/organ/external/O = GET_EXTERNAL_ORGAN(mannequin, bodypart) - if(O && !LAZYACCESS(O.markings, mark_type)) - LAZYSET(O.markings, mark_type, base_markings[mark_type]) - - for(var/obj/item/organ/external/E in mannequin.get_external_organs()) +/decl/bodytype/proc/set_default_sprite_accessories(var/mob/living/setting) + if(!istype(setting)) + return + for(var/obj/item/organ/external/E in setting.get_external_organs()) E.skin_colour = base_color + E.clear_sprite_accessories(skip_update = TRUE) + if(!length(default_sprite_accessories)) + return + for(var/accessory_category in default_sprite_accessories) + for(var/accessory in default_sprite_accessories[accessory_category]) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + var/accessory_colour = default_sprite_accessories[accessory_category][accessory] + for(var/bodypart in accessory_decl.body_parts) + var/obj/item/organ/external/O = GET_EXTERNAL_ORGAN(setting, bodypart) + if(O) + O.set_sprite_accessory(accessory, null, accessory_colour, skip_update = TRUE) +/decl/bodytype/proc/customize_preview_mannequin(mob/living/carbon/human/dummy/mannequin/mannequin) + set_default_sprite_accessories(mannequin) mannequin.set_eye_colour(base_eye_color, skip_update = TRUE) - mannequin.set_hair_colour(base_hair_color, skip_update = TRUE) - mannequin.set_facial_hair_colour(base_hair_color, skip_update = TRUE) - set_default_hair(mannequin) - mannequin.force_update_limbs() mannequin.update_mutations(0) mannequin.update_body(0) diff --git a/code/modules/species/species_bodytype_helpers.dm b/code/modules/species/species_bodytype_helpers.dm index 591054675dc..a92d48f1933 100644 --- a/code/modules/species/species_bodytype_helpers.dm +++ b/code/modules/species/species_bodytype_helpers.dm @@ -21,8 +21,8 @@ /decl/bodytype/proc/get_skeletal_icon(var/mob/living/carbon/human/H) return skeletal_icon -/decl/bodytype/proc/get_lip_icon(var/mob/living/carbon/human/H) - return lip_icon +/decl/bodytype/proc/get_cosmetics_icon(var/decl/sprite_accessory/cosmetics/cosmetics_style) + return cosmetics_icon /decl/bodytype/proc/get_vulnerable_location(var/mob/living/carbon/human/H) return vulnerable_location @@ -33,9 +33,12 @@ /decl/bodytype/proc/handle_post_bodytype_pref_set(datum/preferences/pref) if(!pref) return - // Markings used to be cleared outside of here, but it was always done before every call, so it was moved in here. - pref.body_markings = base_markings?.Copy() + pref.sprite_accessories = list() + for(var/accessory_category in default_sprite_accessories) + pref.sprite_accessories[accessory_category] = list() + for(var/accessory in default_sprite_accessories[accessory_category]) + pref.sprite_accessories[accessory_category][accessory] = default_sprite_accessories[accessory_category][accessory] /decl/bodytype/proc/apply_appearance(var/mob/living/carbon/human/H) if(base_color) diff --git a/code/modules/species/species_bodytype_random.dm b/code/modules/species/species_bodytype_random.dm index ee73c83f994..446b7581764 100644 --- a/code/modules/species/species_bodytype_random.dm +++ b/code/modules/species/species_bodytype_random.dm @@ -1,7 +1,7 @@ #define SETUP_RANDOM_COLOR_GETTER(X, Y, Z, W) \ /decl/bodytype/var/list/random_##Y = W;\ /decl/bodytype/proc/get_random_##X(){\ - if(!(appearance_flags & Z) || !random_##Y.len){\ + if((Z && !(appearance_flags & Z)) || !random_##Y.len){\ return;\ }\ var/decl/color_generator/CG = GET_DECL(pickweight(random_##Y));\ @@ -31,17 +31,6 @@ SETUP_RANDOM_COLOR_GETTER(skin_color, skin_colors, HAS_SKIN_COLOR, list( /decl/color_generator/white)) SETUP_RANDOM_COLOR_SETTER(skin_color, set_skin_colour) -SETUP_RANDOM_COLOR_GETTER(hair_color, hair_colors, HAS_HAIR_COLOR, list( - /decl/color_generator/black, - /decl/color_generator/blonde, - /decl/color_generator/chestnut, - /decl/color_generator/copper, - /decl/color_generator/brown, - /decl/color_generator/wheat, - /decl/color_generator/old, - /decl/color_generator/punk)) -SETUP_RANDOM_COLOR_SETTER(hair_color, set_hair_colour) - SETUP_RANDOM_COLOR_GETTER(eye_color, eye_colors, HAS_EYE_COLOR, list( /decl/color_generator/black, /decl/color_generator/grey, @@ -53,11 +42,6 @@ SETUP_RANDOM_COLOR_GETTER(eye_color, eye_colors, HAS_EYE_COLOR, list( /decl/color_generator/albino_eye)) SETUP_RANDOM_COLOR_SETTER(eye_color, set_eye_colour) -/decl/bodytype/proc/get_random_facial_hair_color() - return get_random_hair_color() - -SETUP_RANDOM_COLOR_SETTER(facial_hair_color, set_facial_hair_colour) - /decl/bodytype/proc/get_random_skin_tone() return random_skin_tone(src) @@ -69,12 +53,4 @@ SETUP_RANDOM_COLOR_SETTER(facial_hair_color, set_facial_hair_colour) if(!isnull(new_tone)) change_skin_tone(new_tone) -/mob/living/carbon/human/proc/randomize_hair_style() - var/list/L = get_valid_hairstyle_types() - set_hairstyle(SAFEPICK(L)) - -/mob/living/carbon/human/proc/randomize_facial_hair_style() - var/list/L = get_valid_facial_hairstyle_types() - set_facial_hairstyle(SAFEPICK(L)) - #undef SETUP_RANDOM_COLOR_GETTER diff --git a/code/modules/species/species_helpers.dm b/code/modules/species/species_helpers.dm index bfeb70b5b74..5ac85615ad4 100644 --- a/code/modules/species/species_helpers.dm +++ b/code/modules/species/species_helpers.dm @@ -39,8 +39,8 @@ var/global/list/stored_shock_by_ref = list() /decl/species/proc/handle_post_species_pref_set(datum/preferences/pref) pref.skin_colour = default_bodytype.base_color pref.eye_colour = default_bodytype.base_eye_color - pref.hair_colour = default_bodytype.base_hair_color - pref.facial_hair_colour = default_bodytype.base_hair_color +// pref.hair_colour = default_bodytype.base_hair_color +// pref.facial_hair_colour = default_bodytype.base_hair_color /decl/species/proc/equip_default_fallback_uniform(var/mob/living/carbon/human/H) if(istype(H)) diff --git a/code/modules/species/species_shapeshifter.dm b/code/modules/species/species_shapeshifter.dm index 2e8a3ba1059..6e770d63a4c 100644 --- a/code/modules/species/species_shapeshifter.dm +++ b/code/modules/species/species_shapeshifter.dm @@ -34,8 +34,8 @@ var/global/list/wrapped_species_by_ref = list() /decl/species/shapeshifter/handle_post_spawn(var/mob/living/carbon/human/H) if(monochromatic) var/skin_colour = H.get_skin_colour() - H.set_hair_colour(skin_colour, skip_update = TRUE) - H.set_facial_hair_colour(skin_colour, skip_update = TRUE) + SET_HAIR_COLOUR(H, skin_colour, TRUE) + SET_FACIAL_HAIR_COLOUR(H, skin_colour, TRUE) ..() /decl/species/shapeshifter/get_pain_emote(var/mob/living/carbon/human/H, var/pain_power) @@ -55,15 +55,15 @@ var/global/list/wrapped_species_by_ref = list() visible_message("\The [src]'s form contorts subtly.") var/decl/bodytype/root_bodytype = get_bodytype() - var/list/hairstyles = species.get_hair_styles(root_bodytype) + var/list/hairstyles = species.get_available_accessory_types(root_bodytype, SAC_HAIR) if(length(hairstyles)) var/decl/sprite_accessory/new_hair = input("Select a hairstyle.", "Shapeshifter Hair") as null|anything in hairstyles - set_hairstyle(new_hair ? new_hair.type : /decl/sprite_accessory/hair/bald) + SET_HAIR_STYLE(src, (new_hair ? new_hair.type : /decl/sprite_accessory/hair/bald), FALSE) - var/list/beardstyles = species.get_facial_hair_styles(root_bodytype) + var/list/beardstyles = species.get_available_accessory_types(root_bodytype, SAC_FACIAL_HAIR) if(length(beardstyles)) var/decl/sprite_accessory/new_hair = input("Select a facial hair style.", "Shapeshifter Hair") as null|anything in beardstyles - set_facial_hairstyle(new_hair ? new_hair.type : /decl/sprite_accessory/facial_hair/shaved) + SET_FACIAL_HAIR_STYLE(src, (new_hair ? new_hair.type : /decl/sprite_accessory/facial_hair/shaved), FALSE) /mob/living/carbon/human/proc/shapeshifter_select_gender() @@ -120,8 +120,8 @@ var/global/list/wrapped_species_by_ref = list() var/decl/species/shapeshifter/S = species if(S.monochromatic) var/skin_colour = get_skin_colour() - set_hair_colour(skin_colour, skip_update = TRUE) - set_facial_hair_colour(skin_colour, skip_update = TRUE) + SET_HAIR_COLOUR(src, skin_colour, TRUE) + SET_FACIAL_HAIR_COLOUR(src, skin_colour, TRUE) for(var/obj/item/organ/external/E in get_external_organs()) E.sync_colour_to_human(src) try_refresh_visible_overlays() diff --git a/code/modules/species/station/human_bodytypes.dm b/code/modules/species/station/human_bodytypes.dm index 402e4d8eb2b..3875657e453 100644 --- a/code/modules/species/station/human_bodytypes.dm +++ b/code/modules/species/station/human_bodytypes.dm @@ -1,19 +1,19 @@ /decl/bodytype/human - name = "feminine" - bodytype_category = BODYTYPE_HUMANOID - icon_base = 'icons/mob/human_races/species/human/body_female.dmi' - icon_deformed = 'icons/mob/human_races/species/human/deformed_body_female.dmi' - lip_icon = 'icons/mob/human_races/species/human/lips.dmi' - blood_overlays = 'icons/mob/human_races/species/human/blood_overlays.dmi' - bandages_icon = 'icons/mob/bandage.dmi' - limb_icon_intensity = 0.7 - associated_gender = FEMALE + name = "feminine" + bodytype_category = BODYTYPE_HUMANOID + cosmetics_icon = 'icons/mob/human_races/species/default_cosmetics.dmi' + icon_base = 'icons/mob/human_races/species/human/body_female.dmi' + icon_deformed = 'icons/mob/human_races/species/human/deformed_body_female.dmi' + blood_overlays = 'icons/mob/human_races/species/human/blood_overlays.dmi' + bandages_icon = 'icons/mob/bandage.dmi' + limb_icon_intensity = 0.7 + associated_gender = FEMALE uniform_state_modifier = "f" - appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE_NORMAL | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR + appearance_flags = HAS_SKIN_TONE_NORMAL | HAS_UNDERWEAR | HAS_EYE_COLOR /decl/bodytype/human/masculine - name = "masculine" - icon_base = 'icons/mob/human_races/species/human/body_male.dmi' - icon_deformed = 'icons/mob/human_races/species/human/deformed_body_male.dmi' - associated_gender = MALE + name = "masculine" + icon_base = 'icons/mob/human_races/species/human/body_male.dmi' + icon_deformed = 'icons/mob/human_races/species/human/deformed_body_male.dmi' + associated_gender = MALE uniform_state_modifier = null \ No newline at end of file diff --git a/code/modules/sprite_accessories/_accessory.dm b/code/modules/sprite_accessories/_accessory.dm index 78ade6f2489..669d10828f6 100644 --- a/code/modules/sprite_accessories/_accessory.dm +++ b/code/modules/sprite_accessories/_accessory.dm @@ -1,6 +1,6 @@ /* - Hello and welcome to sprite_accessories: For sprite accessories, such as hair, + Hello and welcome to sprite accessories: For sprite accessories, such as hair, facial hair, and possibly tattoos and stuff somewhere along the line. This file is intended to be friendly for people with little to no actual coding experience. The process of adding in new hairstyles has been made pain-free and easy to do. @@ -45,10 +45,8 @@ var/hidden_by_gear_slot /// Flag to check equipment for when hiding this accessory. var/hidden_by_gear_flag - /// Whether or not the accessory can be affected by colouration - var/do_colouration = TRUE /// Various flags controlling some checks and behavior. - var/flags = 0 + var/accessory_flags = 0 /// Flags to check when applying this accessory to the mob. var/requires_appearance_flags = 0 /// Icon cache for various icon generation steps. @@ -65,6 +63,15 @@ var/sprite_overlay_layer /// A list of sprite accessory types that are disallowed by this one being included. var/list/disallows_accessories + /// Whether or not this accessory is transferred via DNA (ie. not a scar or tattoo) + var/is_heritable = FALSE + /// What category does this accessory fall under? + var/accessory_category + /// Whether or not this accessory should be drawn on the mob at all. + var/draw_accessory = TRUE + +/decl/sprite_accessory/proc/refresh_mob(var/mob/living/subject) + return /decl/sprite_accessory/proc/accessory_is_available(var/mob/owner, var/decl/species/species, var/decl/bodytype/bodytype) if(species) @@ -94,6 +101,8 @@ /decl/sprite_accessory/validate() . = ..() + if(!ispath(accessory_category, /decl/sprite_accessory_category)) + . += "invalid sprite accessory category: [accessory_category || "null"]" if(!icon) . += "missing icon" else @@ -132,7 +141,7 @@ return null if(mask_to_bodypart) accessory_icon.Blend(get_limb_mask_for(organ.bodytype, organ.organ_tag), ICON_MULTIPLY) - if(do_colouration && color) + if(!isnull(color) && !isnull(color_blend)) accessory_icon.Blend(color, color_blend) cached_icons[organ.bodytype][organ.organ_tag][color] = accessory_icon return accessory_icon diff --git a/code/modules/sprite_accessories/_accessory_category.dm b/code/modules/sprite_accessories/_accessory_category.dm new file mode 100644 index 00000000000..ce41b362ad2 --- /dev/null +++ b/code/modules/sprite_accessories/_accessory_category.dm @@ -0,0 +1,26 @@ +/decl/sprite_accessory_category + decl_flags = DECL_FLAG_MANDATORY_UID + abstract_type = /decl/sprite_accessory_category + /// A name to display in preferences. + var/name + /// A base abstract accessory type for this category. + var/base_accessory_type + /// A maximum number of selections. Ignored if null. + var/max_selections + /// A default always-available type used as a fallback. + var/default_accessory + /// A default colour for the above. + var/default_accessory_color = COLOR_BLACK + /// Set to FALSE for categories where multiple selection is allowed (markings) + var/single_selection = TRUE + /// Set to TRUE to apply these markings as defaults when bodytype is set. + var/always_apply_defaults = FALSE + +/decl/sprite_accessory_category/validate() + . = ..() + if(!name) + . += "no name set" + if(!ispath(base_accessory_type, /decl/sprite_accessory)) + . += "invalid base accessory type: [base_accessory_type || "null"]" + if(single_selection && !default_accessory) + . += "single selection set but no default accessory set" diff --git a/code/modules/sprite_accessories/accessory_cosmetics.dm b/code/modules/sprite_accessories/accessory_cosmetics.dm new file mode 100644 index 00000000000..667a806cea5 --- /dev/null +++ b/code/modules/sprite_accessories/accessory_cosmetics.dm @@ -0,0 +1,62 @@ +/decl/sprite_accessory_category/cosmetics + name = "Cosmetics" + default_accessory = /decl/sprite_accessory/cosmetics/none + base_accessory_type = /decl/sprite_accessory/cosmetics + uid = "acc_cat_cosmetics" + +/decl/sprite_accessory/cosmetics + icon = 'icons/mob/human_races/species/default_cosmetics.dmi' + body_parts = list(BP_HEAD) + color_blend = ICON_MULTIPLY + abstract_type = /decl/sprite_accessory/cosmetics + bodytypes_allowed = null + bodytypes_denied = null + species_allowed = null + subspecies_allowed = null + bodytype_categories_allowed = null + bodytype_categories_denied = null + body_flags_allowed = null + body_flags_denied = null + accessory_category = SAC_COSMETICS + +/decl/sprite_accessory/cosmetics/get_accessory_icon(obj/item/organ/external/organ) + if(!organ || QDELETED(organ)) + return icon + return organ.bodytype?.get_cosmetics_icon(src) + +/decl/sprite_accessory/cosmetics/refresh_mob(var/mob/living/subject) + if(istype(subject)) + subject.update_body() + +/decl/sprite_accessory/cosmetics/accessory_is_available(mob/owner, decl/species/species, decl/bodytype/bodytype) + . = ..() + if(.) + if(!bodytype) + bodytype = owner?.get_bodytype() + return !isnull(bodytype?.get_cosmetics_icon(src)) + +/decl/sprite_accessory/cosmetics/validate() + . = ..() + var/list/all_bodytypes = decls_repository.get_decls_of_type(/decl/bodytype) + for(var/bodytype_type in all_bodytypes) + var/decl/bodytype/bodytype = all_bodytypes[bodytype_type] + var/cosmetics_icon = bodytype.get_cosmetics_icon(src) + if(cosmetics_icon && !check_state_in_icon(icon_state, cosmetics_icon)) + . += "missing icon_state [icon_state] for bodytype [bodytype.type] in icon [bodytype.cosmetics_icon]" + +// Subtypes. +/decl/sprite_accessory/cosmetics/none + name = "No Cosmetics" + icon_state = "nothing" + draw_accessory = FALSE + uid = "acc_cosmetics_nothing" + +/decl/sprite_accessory/cosmetics/lipstick + name = "Lipstick" + icon_state = "lips" + uid = "acc_cosmetics_lips" + +/decl/sprite_accessory/cosmetics/eyeshadow + name = "Eyeshadow" + icon_state = "eyeshadow" + uid = "acc_cosmetics_eyeshadow" diff --git a/code/modules/sprite_accessories/_accessory_facial.dm b/code/modules/sprite_accessories/accessory_facial.dm similarity index 77% rename from code/modules/sprite_accessories/_accessory_facial.dm rename to code/modules/sprite_accessories/accessory_facial.dm index 37a00b5254b..ca836c2955f 100644 --- a/code/modules/sprite_accessories/_accessory_facial.dm +++ b/code/modules/sprite_accessories/accessory_facial.dm @@ -1,33 +1,41 @@ -/* -/////////////////////////////////// -/ =---------------------------= / -/ == Facial Hair Definitions == / -/ =---------------------------= / -/////////////////////////////////// -*/ +/decl/sprite_accessory_category/facial_hair + name = "Facial Hair" + base_accessory_type = /decl/sprite_accessory/facial_hair + default_accessory = /decl/sprite_accessory/facial_hair/shaved + always_apply_defaults = TRUE + uid = "acc_cat_facial_hair" /decl/sprite_accessory/facial_hair - abstract_type = /decl/sprite_accessory/facial_hair - icon = 'icons/mob/human_races/species/human/facial.dmi' - hidden_by_gear_slot = slot_head_str - hidden_by_gear_flag = BLOCK_HEAD_HAIR - body_parts = list(BP_HEAD) + abstract_type = /decl/sprite_accessory/facial_hair + icon = 'icons/mob/human_races/species/human/facial.dmi' + hidden_by_gear_slot = slot_head_str + hidden_by_gear_flag = BLOCK_HEAD_HAIR + body_parts = list(BP_HEAD) + sprite_overlay_layer = FLOAT_LAYER + is_heritable = TRUE + accessory_category = SAC_FACIAL_HAIR + accessory_flags = HAIR_LOSS_VULNERABLE /decl/sprite_accessory/facial_hair/get_hidden_substitute() return GET_DECL(/decl/sprite_accessory/facial_hair/shaved) +/decl/sprite_accessory/facial_hair/refresh_mob(var/mob/living/subject) + if(istype(subject)) + subject.update_hair() + /decl/sprite_accessory/facial_hair/shaved - name = "Shaved" - icon_state = "bald" - bodytypes_allowed = null - bodytypes_denied = null - species_allowed = null - subspecies_allowed = null + name = "Shaved" + icon_state = "bald" + bodytypes_allowed = null + bodytypes_denied = null + species_allowed = null + subspecies_allowed = null bodytype_categories_allowed = null - bodytype_categories_denied = null - body_flags_allowed = null - body_flags_denied = null - uid = "acc_fhair_shaved" + bodytype_categories_denied = null + body_flags_allowed = null + body_flags_denied = null + draw_accessory = FALSE + uid = "acc_fhair_shaved" /decl/sprite_accessory/facial_hair/watson name = "Watson Mustache" diff --git a/code/modules/sprite_accessories/accessory_frills.dm b/code/modules/sprite_accessories/accessory_frills.dm new file mode 100644 index 00000000000..79ed0ddc87c --- /dev/null +++ b/code/modules/sprite_accessories/accessory_frills.dm @@ -0,0 +1,30 @@ +/decl/sprite_accessory_category/frills + name = "Frills" + base_accessory_type = /decl/sprite_accessory/frills + default_accessory = /decl/sprite_accessory/frills/none + uid = "acc_cat_frills" + +/decl/sprite_accessory/frills + hidden_by_gear_slot = slot_head_str + hidden_by_gear_flag = BLOCK_HEAD_HAIR + body_parts = list(BP_HEAD) + sprite_overlay_layer = FLOAT_LAYER + is_heritable = TRUE + icon = 'icons/mob/human_races/species/default_frills.dmi' + accessory_category = SAC_FRILLS + abstract_type = /decl/sprite_accessory/frills + +/decl/sprite_accessory/frills/none + name = "No Frills" + icon_state = "none" + uid = "acc_frills_none" + bodytypes_allowed = null + bodytypes_denied = null + species_allowed = null + subspecies_allowed = null + bodytype_categories_allowed = null + bodytype_categories_denied = null + body_flags_allowed = null + body_flags_denied = null + draw_accessory = FALSE + diff --git a/code/modules/sprite_accessories/_accessory_hair.dm b/code/modules/sprite_accessories/accessory_hair.dm similarity index 72% rename from code/modules/sprite_accessories/_accessory_hair.dm rename to code/modules/sprite_accessories/accessory_hair.dm index 613a52e7259..b9b0e0eda69 100644 --- a/code/modules/sprite_accessories/_accessory_hair.dm +++ b/code/modules/sprite_accessories/accessory_hair.dm @@ -1,47 +1,55 @@ -/* -//////////////////////////// -/ =--------------------= / -/ == Hair Definitions == / -/ =--------------------= / -//////////////////////////// -*/ +/decl/sprite_accessory_category/hair + name = "Hair" + base_accessory_type = /decl/sprite_accessory/hair + default_accessory = /decl/sprite_accessory/hair/bald + always_apply_defaults = TRUE + uid = "acc_cat_hair" /decl/sprite_accessory/hair - abstract_type = /decl/sprite_accessory/hair - icon = 'icons/mob/human_races/species/human/hair.dmi' - hidden_by_gear_slot = slot_head_str - hidden_by_gear_flag = BLOCK_HEAD_HAIR - body_parts = list(BP_HEAD) + abstract_type = /decl/sprite_accessory/hair + icon = 'icons/mob/human_races/species/human/hair.dmi' + hidden_by_gear_slot = slot_head_str + hidden_by_gear_flag = BLOCK_HEAD_HAIR + body_parts = list(BP_HEAD) + sprite_overlay_layer = FLOAT_LAYER + is_heritable = TRUE + accessory_category = SAC_HAIR + accessory_flags = HAIR_LOSS_VULNERABLE /decl/sprite_accessory/hair/get_hidden_substitute() - if(flags & VERY_SHORT) + if(accessory_flags & VERY_SHORT) return src return GET_DECL(/decl/sprite_accessory/hair/short) +/decl/sprite_accessory/hair/refresh_mob(var/mob/living/subject) + if(istype(subject)) + subject.update_hair() + /decl/sprite_accessory/hair/bald - name = "Bald" - icon_state = "bald" - flags = VERY_SHORT | HAIR_BALD - bodytypes_allowed = null - bodytypes_denied = null - species_allowed = null - subspecies_allowed = null + name = "Bald" + icon_state = "bald" + accessory_flags = VERY_SHORT | HAIR_BALD + bodytypes_allowed = null + bodytypes_denied = null + species_allowed = null + subspecies_allowed = null bodytype_categories_allowed = null - bodytype_categories_denied = null - body_flags_allowed = null - body_flags_denied = null - uid = "acc_hair_bald" + bodytype_categories_denied = null + body_flags_allowed = null + body_flags_denied = null + draw_accessory = FALSE + uid = "acc_hair_bald" /decl/sprite_accessory/hair/short name = "Short Hair" // try to capatilize the names please~ icon_state = "hair_a" // you do not need to define _s or _l sub-states, game automatically does this for you - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_short" /decl/sprite_accessory/hair/twintail name = "Twintail" icon_state = "hair_twintail" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_twintail" /decl/sprite_accessory/hair/short2 @@ -52,43 +60,43 @@ /decl/sprite_accessory/hair/cut name = "Cut Hair" icon_state = "hair_c" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_cut" /decl/sprite_accessory/hair/flair name = "Flaired Hair" icon_state = "hair_flair" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_flair" /decl/sprite_accessory/hair/long name = "Shoulder-length Hair" icon_state = "hair_b" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_shoulder" /decl/sprite_accessory/hair/longer name = "Long Hair" icon_state = "hair_vlong" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_long" /decl/sprite_accessory/hair/longest name = "Very Long Hair" icon_state = "hair_longest" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_verylong" /decl/sprite_accessory/hair/longfringe name = "Long Fringe" icon_state = "hair_longfringe" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_longfringe" /decl/sprite_accessory/hair/longestalt name = "Longer Fringe" icon_state = "hair_vlongfringe" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_longestalt" /decl/sprite_accessory/hair/halfbang @@ -104,43 +112,43 @@ /decl/sprite_accessory/hair/ponytail1 name = "Ponytail 1" icon_state = "hair_ponytail" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_ponytail1" /decl/sprite_accessory/hair/ponytail2 name = "Ponytail 2" icon_state = "hair_pa" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_ponytail2" /decl/sprite_accessory/hair/ponytail3 name = "Ponytail 3" icon_state = "hair_ponytail3" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_ponytail3" /decl/sprite_accessory/hair/ponytail4 name = "Ponytail 4" icon_state = "hair_ponytail4" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_ponytail4" /decl/sprite_accessory/hair/ponytail5 name = "Ponytail 5" icon_state = "hair_ponytail5" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_ponytail5" /decl/sprite_accessory/hair/ponytail6 name = "Ponytail 6" icon_state = "hair_ponytail6" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_ponytail6" /decl/sprite_accessory/hair/sideponytail name = "Side Ponytail" icon_state = "hair_stail" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_sideponytail" /decl/sprite_accessory/hair/parted @@ -156,7 +164,7 @@ /decl/sprite_accessory/hair/sleeze name = "Sleeze" icon_state = "hair_sleeze" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_sleeze" /decl/sprite_accessory/hair/quiff @@ -177,13 +185,13 @@ /decl/sprite_accessory/hair/bedhead3 name = "Bedhead 3" icon_state = "hair_bedheadv3" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_bedhead3" /decl/sprite_accessory/hair/beehive name = "Beehive" icon_state = "hair_beehive" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_beehive" /decl/sprite_accessory/hair/beehive2 @@ -194,19 +202,19 @@ /decl/sprite_accessory/hair/bobcurl name = "Bobcurl" icon_state = "hair_bobcurl" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_bobcurl" /decl/sprite_accessory/hair/bob name = "Bob" icon_state = "hair_bobcut" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_bob" /decl/sprite_accessory/hair/bobcutalt name = "Chin Length Bob" icon_state = "hair_bobcutalt" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_bobcutalt" /decl/sprite_accessory/hair/bowl @@ -217,13 +225,13 @@ /decl/sprite_accessory/hair/buzz name = "Buzzcut" icon_state = "hair_buzzcut" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_buzz" /decl/sprite_accessory/hair/crew name = "Crewcut" icon_state = "hair_crewcut" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_crew" /decl/sprite_accessory/hair/combover @@ -254,7 +262,7 @@ /decl/sprite_accessory/hair/curls name = "Curls" icon_state = "hair_curls" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_curls" /decl/sprite_accessory/hair/afro @@ -275,19 +283,19 @@ /decl/sprite_accessory/hair/rows name = "Rows" icon_state = "hair_rows1" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_rows" /decl/sprite_accessory/hair/rows2 name = "Rows 2" icon_state = "hair_rows2" - flags = VERY_SHORT | HAIR_TIEABLE + accessory_flags = VERY_SHORT | HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_rows2" /decl/sprite_accessory/hair/sargeant name = "Flat Top" icon_state = "hair_sargeant" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_flattop" /decl/sprite_accessory/hair/emo @@ -303,19 +311,19 @@ /decl/sprite_accessory/hair/longemo name = "Long Emo" icon_state = "hair_emolong" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_longemo" /decl/sprite_accessory/hair/shortovereye name = "Overeye Short" icon_state = "hair_shortovereye" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_overeye_short" /decl/sprite_accessory/hair/longovereye name = "Overeye Long" icon_state = "hair_longovereye" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_overeye_long" /decl/sprite_accessory/hair/flow @@ -326,7 +334,7 @@ /decl/sprite_accessory/hair/feather name = "Feather" icon_state = "hair_feather" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_feather" /decl/sprite_accessory/hair/hitop @@ -352,7 +360,7 @@ /decl/sprite_accessory/hair/gentle name = "Gentle" icon_state = "hair_gentle" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_gentle" /decl/sprite_accessory/hair/spiky @@ -368,67 +376,67 @@ /decl/sprite_accessory/hair/kagami name = "Pigtails" icon_state = "hair_kagami" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_kagami" /decl/sprite_accessory/hair/himecut name = "Hime Cut" icon_state = "hair_himecut" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_himecut" /decl/sprite_accessory/hair/shorthime name = "Short Hime Cut" icon_state = "hair_shorthime" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_shorthime" /decl/sprite_accessory/hair/grandebraid name = "Grande Braid" icon_state = "hair_grande" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_grande" /decl/sprite_accessory/hair/mbraid name = "Medium Braid" icon_state = "hair_shortbraid" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_mbraid" /decl/sprite_accessory/hair/braid2 name = "Long Braid" icon_state = "hair_hbraid" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_braid2" /decl/sprite_accessory/hair/odango name = "Odango" icon_state = "hair_odango" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_odango" /decl/sprite_accessory/hair/ombre name = "Ombre" icon_state = "hair_ombre" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_ombre" /decl/sprite_accessory/hair/updo name = "Updo" icon_state = "hair_updo" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_updo" /decl/sprite_accessory/hair/skinhead name = "Skinhead" icon_state = "hair_skinhead" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_skinhead" /decl/sprite_accessory/hair/balding name = "Balding Hair" icon_state = "hair_e" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_balding" /decl/sprite_accessory/hair/familyman @@ -439,13 +447,13 @@ /decl/sprite_accessory/hair/mahdrills name = "Drillruru" icon_state = "hair_drillruru" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_drillruru" /decl/sprite_accessory/hair/fringetail name = "Fringetail" icon_state = "hair_fringetail" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_fringetail" /decl/sprite_accessory/hair/dandypomp @@ -456,7 +464,7 @@ /decl/sprite_accessory/hair/poofy name = "Poofy" icon_state = "hair_poofy" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_poofy" /decl/sprite_accessory/hair/crono @@ -487,7 +495,7 @@ /decl/sprite_accessory/hair/nitori name = "Nitori" icon_state = "hair_nitori" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_nitori" /decl/sprite_accessory/hair/joestar @@ -498,13 +506,13 @@ /decl/sprite_accessory/hair/volaju name = "Volaju" icon_state = "hair_volaju" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_volaju" /decl/sprite_accessory/hair/longeralt2 name = "Long Hair Alt 2" icon_state = "hair_longeralt2" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_longeralt2" /decl/sprite_accessory/hair/shortbangs @@ -515,157 +523,157 @@ /decl/sprite_accessory/hair/shavedbun name = "Shaved Bun" icon_state = "hair_shavedbun" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_shavedbun" /decl/sprite_accessory/hair/halfshaved name = "Half-Shaved" icon_state = "hair_halfshaved" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_halfshaved" /decl/sprite_accessory/hair/halfshavedemo name = "Half-Shaved Emo" icon_state = "hair_halfshavedemo" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_halfshavedemo" /decl/sprite_accessory/hair/longsideemo name = "Long Side Emo" icon_state = "hair_longsideemo" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_longsideemo" /decl/sprite_accessory/hair/bun name = "Low Bun" icon_state = "hair_bun" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_lowbun" /decl/sprite_accessory/hair/bun2 name = "High Bun" icon_state = "hair_bun2" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_highbun" /decl/sprite_accessory/hair/doublebun name = "Double-Bun" icon_state = "hair_doublebun" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_doublebun" /decl/sprite_accessory/hair/lowfade name = "Low Fade" icon_state = "hair_lowfade" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_lowfade" /decl/sprite_accessory/hair/medfade name = "Medium Fade" icon_state = "hair_medfade" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_medfade" /decl/sprite_accessory/hair/highfade name = "High Fade" icon_state = "hair_highfade" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_highfade" /decl/sprite_accessory/hair/baldfade name = "Balding Fade" icon_state = "hair_baldfade" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_baldfade" /decl/sprite_accessory/hair/nofade name = "Regulation Cut" icon_state = "hair_nofade" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_nofade" /decl/sprite_accessory/hair/trimflat name = "Trimmed Flat Top" icon_state = "hair_trimflat" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_trimflat" /decl/sprite_accessory/hair/shaved name = "Shaved" icon_state = "hair_shaved" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_shaved" /decl/sprite_accessory/hair/trimmed name = "Trimmed" icon_state = "hair_trimmed" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_trimmed" /decl/sprite_accessory/hair/tightbun name = "Tight Bun" icon_state = "hair_tightbun" - flags = VERY_SHORT | HAIR_TIEABLE + accessory_flags = VERY_SHORT | HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_tightbun" /decl/sprite_accessory/hair/coffeehouse name = "Coffee House Cut" icon_state = "hair_coffeehouse" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_coffeehouse" /decl/sprite_accessory/hair/undercut name = "Undercut" icon_state = "hair_undercut" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_undercut" /decl/sprite_accessory/hair/partfade name = "Parted Fade" icon_state = "hair_shavedpart" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_partfade" /decl/sprite_accessory/hair/hightight name = "High and Tight" icon_state = "hair_hightight" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_hightight" /decl/sprite_accessory/hair/rowbun name = "Row Bun" icon_state = "hair_rowbun" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_rowbun" /decl/sprite_accessory/hair/rowdualbraid name = "Row Dual Braid" icon_state = "hair_rowdualtail" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_rowdualbraid" /decl/sprite_accessory/hair/rowbraid name = "Row Braid" icon_state = "hair_rowbraid" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_rowbraid" /decl/sprite_accessory/hair/regulationmohawk name = "Regulation Mohawk" icon_state = "hair_shavedmohawk" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_regulationmohawk" /decl/sprite_accessory/hair/topknot name = "Topknot" icon_state = "hair_topknot" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_topknot" /decl/sprite_accessory/hair/ronin name = "Ronin" icon_state = "hair_ronin" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_ronin" /decl/sprite_accessory/hair/bowlcut2 @@ -676,25 +684,25 @@ /decl/sprite_accessory/hair/thinning name = "Thinning" icon_state = "hair_thinning" - flags = VERY_SHORT + accessory_flags = VERY_SHORT uid = "acc_hair_thinning" /decl/sprite_accessory/hair/thinningfront name = "Thinning Front" icon_state = "hair_thinningfront" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_thinningfront" /decl/sprite_accessory/hair/thinningback name = "Thinning Back" icon_state = "hair_thinningrear" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_thinningback" /decl/sprite_accessory/hair/manbun name = "Manbun" icon_state = "hair_manbun" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_manbun" /decl/sprite_accessory/hair/leftsidecut @@ -715,7 +723,7 @@ /decl/sprite_accessory/hair/messyhair name = "Messy" icon_state = "hair_messyhair" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_messyhair" /decl/sprite_accessory/hair/averagejoe @@ -746,19 +754,19 @@ /decl/sprite_accessory/hair/amazon name = "Amazon" icon_state = "hair_amazon" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_amazon" /decl/sprite_accessory/hair/straightlong name = "Straight Long" icon_state = "hair_straightlong" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_straightlong" /decl/sprite_accessory/hair/marysue name = "Mary Sue" icon_state = "hair_marysue" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_marysue" /decl/sprite_accessory/hair/messyhair2 @@ -774,7 +782,7 @@ /decl/sprite_accessory/hair/sideundercut name = "Side Undercut" icon_state = "hair_sideundercut" - flags = VERY_SHORT + accessory_flags = VERY_SHORT | HAIR_LOSS_VULNERABLE uid = "acc_hair_sideundercut" /decl/sprite_accessory/hair/bighawk @@ -785,23 +793,23 @@ /decl/sprite_accessory/hair/donutbun name = "Donut Bun" icon_state = "hair_donutbun" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_donutbun" /decl/sprite_accessory/hair/gentle2 name = "Gentle 2" icon_state = "hair_gentle2" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_gentle2" /decl/sprite_accessory/hair/gentle2long name = "Gentle 2 Long" icon_state = "hair_gentle2long" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_gentle2long" /decl/sprite_accessory/hair/trimrsidecut name = "Trimmed Right Sidecut" icon_state = "hair_rightside_trim" - flags = HAIR_TIEABLE + accessory_flags = HAIR_TIEABLE | HAIR_LOSS_VULNERABLE uid = "acc_hair_trimrightsidecut" diff --git a/code/modules/sprite_accessories/accessory_horns.dm b/code/modules/sprite_accessories/accessory_horns.dm new file mode 100644 index 00000000000..4d1218c3151 --- /dev/null +++ b/code/modules/sprite_accessories/accessory_horns.dm @@ -0,0 +1,29 @@ +/decl/sprite_accessory_category/horns + name = "Horns" + base_accessory_type = /decl/sprite_accessory/horns + default_accessory = /decl/sprite_accessory/horns/none + uid = "acc_cat_horns" + +/decl/sprite_accessory/horns + hidden_by_gear_slot = slot_head_str + hidden_by_gear_flag = BLOCK_HEAD_HAIR + body_parts = list(BP_HEAD) + sprite_overlay_layer = FLOAT_LAYER + is_heritable = TRUE + icon = 'icons/mob/human_races/species/default_horns.dmi' + accessory_category = SAC_HORNS + abstract_type = /decl/sprite_accessory/horns + +/decl/sprite_accessory/horns/none + name = "No Horns" + icon_state = "none" + uid = "acc_horns_none" + bodytypes_allowed = null + bodytypes_denied = null + species_allowed = null + subspecies_allowed = null + bodytype_categories_allowed = null + bodytype_categories_denied = null + body_flags_allowed = null + body_flags_denied = null + draw_accessory = FALSE diff --git a/code/modules/sprite_accessories/_accessory_markings.dm b/code/modules/sprite_accessories/accessory_markings.dm similarity index 85% rename from code/modules/sprite_accessories/_accessory_markings.dm rename to code/modules/sprite_accessories/accessory_markings.dm index 6abf3c86e31..a55d64910b1 100644 --- a/code/modules/sprite_accessories/_accessory_markings.dm +++ b/code/modules/sprite_accessories/accessory_markings.dm @@ -1,9 +1,18 @@ -//body markings +/decl/sprite_accessory_category/markings + name = "Markings" + single_selection = FALSE + base_accessory_type = /decl/sprite_accessory/marking + uid = "acc_cat_markings" + /decl/sprite_accessory/marking - icon = 'icons/mob/human_races/species/default_markings.dmi' - do_colouration = 1 //Almost all of them have it, COLOR_ADD - abstract_type = /decl/sprite_accessory/marking - mask_to_bodypart = TRUE + icon = 'icons/mob/human_races/species/default_markings.dmi' + abstract_type = /decl/sprite_accessory/marking + mask_to_bodypart = TRUE + accessory_category = SAC_MARKINGS + +/decl/sprite_accessory/marking/refresh_mob(var/mob/living/subject) + if(istype(subject)) + subject.update_body() /decl/sprite_accessory/marking/tat_hive name = "Tattoo (Hive, Back)" diff --git a/icons/mob/human_races/species/default_cosmetics.dmi b/icons/mob/human_races/species/default_cosmetics.dmi new file mode 100644 index 00000000000..f2e9eb20b07 Binary files /dev/null and b/icons/mob/human_races/species/default_cosmetics.dmi differ diff --git a/icons/mob/human_races/species/default_frills.dmi b/icons/mob/human_races/species/default_frills.dmi new file mode 100644 index 00000000000..4e445d46e06 Binary files /dev/null and b/icons/mob/human_races/species/default_frills.dmi differ diff --git a/icons/mob/human_races/species/default_horns.dmi b/icons/mob/human_races/species/default_horns.dmi new file mode 100644 index 00000000000..4e445d46e06 Binary files /dev/null and b/icons/mob/human_races/species/default_horns.dmi differ diff --git a/icons/mob/human_races/species/lips.dmi b/icons/mob/human_races/species/lips.dmi deleted file mode 100644 index 42e9e7f2b6f..00000000000 Binary files a/icons/mob/human_races/species/lips.dmi and /dev/null differ diff --git a/icons/obj/items/cosmetics/eyeshadow.dmi b/icons/obj/items/cosmetics/eyeshadow.dmi new file mode 100644 index 00000000000..ff06f346f4c Binary files /dev/null and b/icons/obj/items/cosmetics/eyeshadow.dmi differ diff --git a/icons/obj/items/cosmetics/lipstick.dmi b/icons/obj/items/cosmetics/lipstick.dmi new file mode 100644 index 00000000000..5715e4b1c7c Binary files /dev/null and b/icons/obj/items/cosmetics/lipstick.dmi differ diff --git a/icons/obj/items/lipstick.dmi b/icons/obj/items/lipstick.dmi deleted file mode 100644 index 6d5c07d6d1a..00000000000 Binary files a/icons/obj/items/lipstick.dmi and /dev/null differ diff --git a/maps/away/unishi/unishi-3.dmm b/maps/away/unishi/unishi-3.dmm index e91221f4215..b860d0c7252 100644 --- a/maps/away/unishi/unishi-3.dmm +++ b/maps/away/unishi/unishi-3.dmm @@ -1721,9 +1721,9 @@ "eJ" = ( /obj/structure/table/woodentable, /obj/item/haircomb/brush, -/obj/item/lipstick/black, -/obj/item/lipstick/green, -/obj/item/lipstick/violet, +/obj/item/cosmetics/lipstick/black, +/obj/item/cosmetics/lipstick/green, +/obj/item/cosmetics/lipstick/violet, /obj/random/drinkbottle, /turf/simulated/floor/wood, /area/unishi/living) diff --git a/mods/content/corporate/datum/robolimbs.dm b/mods/content/corporate/datum/robolimbs.dm index 841249d2836..2b72d5a2089 100644 --- a/mods/content/corporate/datum/robolimbs.dm +++ b/mods/content/corporate/datum/robolimbs.dm @@ -82,7 +82,7 @@ name = "Vey-Med (Feminine)" desc = "This high quality limb is nearly indistinguishable from an organic one." icon_base = 'mods/content/corporate/icons/cyberlimbs/veymed/veymed_female.dmi' - appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE_NORMAL | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR + appearance_flags = HAS_SKIN_TONE_NORMAL | HAS_UNDERWEAR | HAS_EYE_COLOR body_flags = BODY_FLAG_NO_DNA | BODY_FLAG_NO_DEFIB | BODY_FLAG_NO_STASIS bodytype_category = BODYTYPE_HUMANOID // todo: add synthflesh material? diff --git a/mods/species/bayliens/skrell/datum/species_bodytype.dm b/mods/species/bayliens/skrell/datum/species_bodytype.dm index 2203188c040..1cd6ebc4f3d 100644 --- a/mods/species/bayliens/skrell/datum/species_bodytype.dm +++ b/mods/species/bayliens/skrell/datum/species_bodytype.dm @@ -1,19 +1,25 @@ /decl/bodytype/skrell - name = BODYTYPE_SKRELL - icon_base = 'mods/species/bayliens/skrell/icons/body/body.dmi' - bandages_icon = 'icons/mob/bandage.dmi' - bandages_icon = 'icons/mob/bandage.dmi' + name = BODYTYPE_SKRELL + icon_base = 'mods/species/bayliens/skrell/icons/body/body.dmi' + bandages_icon = 'icons/mob/bandage.dmi' + bandages_icon = 'icons/mob/bandage.dmi' health_hud_intensity = 1.75 - associated_gender = PLURAL - eye_darksight_range = 4 - eye_flash_mod = 1.2 - eye_icon = 'mods/species/bayliens/skrell/icons/body/eyes.dmi' - apply_eye_colour = FALSE + associated_gender = PLURAL + eye_darksight_range = 4 + eye_flash_mod = 1.2 + eye_icon = 'mods/species/bayliens/skrell/icons/body/eyes.dmi' + apply_eye_colour = FALSE + + associated_gender = PLURAL + appearance_flags = HAS_UNDERWEAR | HAS_SKIN_COLOR + base_color = "#006666" + + default_sprite_accessories = list( + SAC_HAIR = list( + /decl/sprite_accessory/hair/skrell/short = "#006666" + ) + ) - associated_gender = PLURAL - appearance_flags = HAS_HAIR_COLOR | HAS_UNDERWEAR | HAS_SKIN_COLOR - base_color = "#006666" - base_hair_color = "#006666" has_organ = list( BP_HEART = /obj/item/organ/internal/heart, BP_STOMACH = /obj/item/organ/internal/stomach, @@ -23,7 +29,6 @@ BP_BRAIN = /obj/item/organ/internal/brain, BP_EYES = /obj/item/organ/internal/eyes/skrell ) - default_h_style = /decl/sprite_accessory/hair/skrell/short cold_level_1 = 280 //Default 260 - Lower is better cold_level_2 = 220 //Default 200 diff --git a/mods/species/bayliens/tajaran/datum/accessory.dm b/mods/species/bayliens/tajaran/datum/accessory.dm index d9f0ab3d3f6..e8aa5689d7d 100644 --- a/mods/species/bayliens/tajaran/datum/accessory.dm +++ b/mods/species/bayliens/tajaran/datum/accessory.dm @@ -209,7 +209,7 @@ name = "Patches (Body)" icon_state = "patches" body_parts = list(BP_CHEST, BP_GROIN) - flags = HAIR_LOSS_VULNERABLE + accessory_flags = HAIR_LOSS_VULNERABLE uid = "acc_marking_taj_patches" /decl/sprite_accessory/marking/tajaran/patches/left_arm @@ -235,7 +235,7 @@ /decl/sprite_accessory/marking/tajaran/tiger name = "Tiger Stripes (Head)" icon_state = "tiger" - flags = HAIR_LOSS_VULNERABLE + accessory_flags = HAIR_LOSS_VULNERABLE uid = "acc_marking_taj_tiger_head" /decl/sprite_accessory/marking/tajaran/tiger/body @@ -266,7 +266,7 @@ /decl/sprite_accessory/marking/tajaran/spots name = "Spots (Head)" icon_state = "spots" - flags = HAIR_LOSS_VULNERABLE + accessory_flags = HAIR_LOSS_VULNERABLE uid = "acc_marking_taj_spots_head" /decl/sprite_accessory/marking/tajaran/spots/body @@ -298,7 +298,7 @@ name = "Pawsocks (Left Arm)" icon_state = "pawsocks" body_parts = list(BP_L_ARM, BP_L_HAND) - flags = HAIR_LOSS_VULNERABLE + accessory_flags = HAIR_LOSS_VULNERABLE uid = "acc_marking_taj_pawsocks_leftarm" /decl/sprite_accessory/marking/tajaran/pawsocks/right_arm @@ -320,5 +320,5 @@ name = "Belly" icon_state = "belly" body_parts = list(BP_CHEST, BP_GROIN) - flags = HAIR_LOSS_VULNERABLE + accessory_flags = HAIR_LOSS_VULNERABLE uid = "acc_marking_taj_belly" diff --git a/mods/species/bayliens/tajaran/datum/species_bodytypes.dm b/mods/species/bayliens/tajaran/datum/species_bodytypes.dm index bc1579552a6..5bdcf07731d 100644 --- a/mods/species/bayliens/tajaran/datum/species_bodytypes.dm +++ b/mods/species/bayliens/tajaran/datum/species_bodytypes.dm @@ -1,33 +1,34 @@ /decl/bodytype/feline - name = "humanoid" - bodytype_category = BODYTYPE_FELINE - limb_blend = ICON_MULTIPLY - icon_template = 'mods/species/bayliens/tajaran/icons/template.dmi' - icon_base = 'mods/species/bayliens/tajaran/icons/body.dmi' - icon_deformed = 'mods/species/bayliens/tajaran/icons/deformed_body.dmi' - bandages_icon = 'icons/mob/bandage.dmi' - lip_icon = 'mods/species/bayliens/tajaran/icons/lips.dmi' + name = "humanoid" + bodytype_category = BODYTYPE_FELINE + limb_blend = ICON_MULTIPLY + icon_template = 'mods/species/bayliens/tajaran/icons/template.dmi' + icon_base = 'mods/species/bayliens/tajaran/icons/body.dmi' + icon_deformed = 'mods/species/bayliens/tajaran/icons/deformed_body.dmi' + bandages_icon = 'icons/mob/bandage.dmi' + cosmetics_icon = 'mods/species/bayliens/tajaran/icons/cosmetics.dmi' health_hud_intensity = 1.75 - bodytype_flag = BODY_FLAG_FELINE - movement_slowdown = -0.5 - appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR - base_hair_color = "#46321c" - base_color = "#ae7d32" - base_eye_color = "#00aa00" - default_h_style = /decl/sprite_accessory/hair/taj/lynx - - eye_darksight_range = 7 - eye_flash_mod = 2 - eye_blend = ICON_MULTIPLY - eye_icon = 'mods/species/bayliens/tajaran/icons/eyes.dmi' - eye_low_light_vision_effectiveness = 0.15 + bodytype_flag = BODY_FLAG_FELINE + movement_slowdown = -0.5 + appearance_flags = HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR + base_color = "#ae7d32" + base_eye_color = "#00aa00" + + eye_darksight_range = 7 + eye_flash_mod = 2 + eye_blend = ICON_MULTIPLY + eye_icon = 'mods/species/bayliens/tajaran/icons/eyes.dmi' + eye_low_light_vision_effectiveness = 0.15 eye_low_light_vision_adjustment_speed = 0.3 override_limb_types = list( BP_TAIL = /obj/item/organ/external/tail/cat ) - base_markings = list(/decl/sprite_accessory/marking/tajaran/ears = "#ae7d32") + default_sprite_accessories = list( + SAC_HAIR = list(/decl/sprite_accessory/hair/taj/lynx = "#46321c"), + SAC_MARKINGS = list(/decl/sprite_accessory/marking/tajaran/ears = "#ae7d32") + ) cold_level_1 = 200 cold_level_2 = 140 @@ -37,8 +38,8 @@ heat_level_2 = 380 heat_level_3 = 800 - heat_discomfort_level = 294 - cold_discomfort_level = 230 + heat_discomfort_level = 294 + cold_discomfort_level = 230 heat_discomfort_strings = list( "Your fur prickles in the heat.", "You feel uncomfortably warm.", diff --git a/mods/species/bayliens/tajaran/icons/cosmetics.dmi b/mods/species/bayliens/tajaran/icons/cosmetics.dmi new file mode 100644 index 00000000000..3d7d37d45c4 Binary files /dev/null and b/mods/species/bayliens/tajaran/icons/cosmetics.dmi differ diff --git a/mods/species/bayliens/tajaran/icons/lips.dmi b/mods/species/bayliens/tajaran/icons/lips.dmi deleted file mode 100644 index 0586f9438ab..00000000000 Binary files a/mods/species/bayliens/tajaran/icons/lips.dmi and /dev/null differ diff --git a/mods/species/bayliens/tritonian/datum/species_bodytypes.dm b/mods/species/bayliens/tritonian/datum/species_bodytypes.dm index 12253390a8c..2f4881f38ea 100644 --- a/mods/species/bayliens/tritonian/datum/species_bodytypes.dm +++ b/mods/species/bayliens/tritonian/datum/species_bodytypes.dm @@ -1,7 +1,7 @@ /decl/bodytype/human/tritonian icon_base = 'mods/species/bayliens/tritonian/icons/body_female.dmi' movement_slowdown = 0.5 - appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE_TRITON | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR + appearance_flags = HAS_SKIN_TONE_TRITON | HAS_UNDERWEAR | HAS_EYE_COLOR override_organ_types = list( BP_LUNGS = /obj/item/organ/internal/lungs/gills ) diff --git a/mods/species/bayliens/unathi/datum/species.dm b/mods/species/bayliens/unathi/datum/species.dm index 664bf3ee73b..29cd9e8d913 100644 --- a/mods/species/bayliens/unathi/datum/species.dm +++ b/mods/species/bayliens/unathi/datum/species.dm @@ -28,6 +28,13 @@ /decl/natural_attack/bite/sharp ) + available_accessory_categories = list( + SAC_HORNS, + SAC_FRILLS, + SAC_COSMETICS, + SAC_MARKINGS + ) + primitive_form = "Stok" gluttonous = GLUT_TINY strength = STR_HIGH diff --git a/mods/species/bayliens/unathi/datum/species_bodytypes.dm b/mods/species/bayliens/unathi/datum/species_bodytypes.dm index 7b2af8f5de2..f2aafcd19a6 100644 --- a/mods/species/bayliens/unathi/datum/species_bodytypes.dm +++ b/mods/species/bayliens/unathi/datum/species_bodytypes.dm @@ -4,7 +4,7 @@ husk_icon = 'mods/species/bayliens/unathi/icons/husk.dmi' icon_base = 'mods/species/bayliens/unathi/icons/body_female.dmi' icon_deformed = 'mods/species/bayliens/unathi/icons/deformed_body_female.dmi' - lip_icon = 'mods/species/bayliens/unathi/icons/lips.dmi' + cosmetics_icon = 'mods/species/bayliens/unathi/icons/cosmetics.dmi' blood_overlays = 'icons/mob/human_races/species/human/blood_overlays.dmi' bandages_icon = 'icons/mob/bandage.dmi' limb_icon_intensity = 0.7 @@ -13,11 +13,16 @@ uniform_state_modifier = "_f" movement_slowdown = 0.5 base_color = "#066000" - base_hair_color = "#192e19" - appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR + appearance_flags = HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR eye_darksight_range = 3 eye_flash_mod = 1.2 + default_sprite_accessories = list( + SAC_FRILLS = list( + /decl/sprite_accessory/frills/lizard/frills_long = "#192e19" + ) + ) + override_organ_types = list( BP_EYES = /obj/item/organ/internal/eyes/lizard, BP_BRAIN = /obj/item/organ/internal/brain/lizard @@ -25,8 +30,6 @@ override_limb_types = list(BP_TAIL = /obj/item/organ/external/tail/lizard) - default_h_style = /decl/sprite_accessory/hair/lizard/frills_long - cold_level_1 = 280 //Default 260 - Lower is better cold_level_2 = 220 //Default 200 cold_level_3 = 130 //Default 120 diff --git a/mods/species/bayliens/unathi/datum/sprite_accessory.dm b/mods/species/bayliens/unathi/datum/sprite_accessory.dm index f8a71288a66..d59bbb6bada 100644 --- a/mods/species/bayliens/unathi/datum/sprite_accessory.dm +++ b/mods/species/bayliens/unathi/datum/sprite_accessory.dm @@ -1,112 +1,112 @@ -/decl/sprite_accessory/hair/lizard +/decl/sprite_accessory/horns/lizard name = "Lizard Horns" - icon = 'mods/species/bayliens/unathi/icons/hair.dmi' + icon = 'mods/species/bayliens/unathi/icons/horns.dmi' icon_state = "horns" species_allowed = list(SPECIES_LIZARD) color_blend = ICON_MULTIPLY - flags = VERY_SHORT + accessory_flags = VERY_SHORT uid = "acc_hair_una_horns" -/decl/sprite_accessory/hair/lizard/hood - name = "Lizard Cobra Hood" - icon_state = "cobrahood" - uid = "acc_hair_una_cobra" - -/decl/sprite_accessory/hair/lizard/spines_long +/decl/sprite_accessory/horns/lizard/spines_long name = "Lizard Spines Long" icon_state = "spines_long" uid = "acc_hair_una_longspines" -/decl/sprite_accessory/hair/lizard/spines_short +/decl/sprite_accessory/horns/lizard/spines_short name = "Lizard Spines Short" icon_state = "spines_short" uid = "acc_hair_una_shortspines" -/decl/sprite_accessory/hair/lizard/frills_aqua - name = "Lizard Frills Aqua" - icon_state = "frills_aqua" - uid = "acc_hair_una_aqua" - -/decl/sprite_accessory/hair/lizard/frills_long - name = "Lizard Frills Long" - icon_state = "frills_long" - uid = "acc_hair_una_longfrills" - -/decl/sprite_accessory/hair/lizard/frills_short - name = "Lizard Frills Short" - icon_state = "frills_short" - uid = "acc_hair_una_shortfrills" - -/decl/sprite_accessory/hair/lizard/sidefrills - name = "Lizard Frills Side" - icon_state = "frills_side" - uid = "acc_hair_una_sidefrills" - -/decl/sprite_accessory/hair/lizard/bighorns +/decl/sprite_accessory/horns/lizard/bighorns name = "Lizard Horns Big" icon_state = "horns_big" uid = "acc_hair_una_bighorns" -/decl/sprite_accessory/hair/lizard/smallhorns +/decl/sprite_accessory/horns/lizard/smallhorns name = "Lizard Horns Small" icon_state = "horns_small" uid = "acc_hair_una_smallhorns" -/decl/sprite_accessory/hair/lizard/shorthorns +/decl/sprite_accessory/horns/lizard/shorthorns name = "Lizard Horns Short" icon_state = "horns_short" uid = "acc_hair_una_shorthorns" -/decl/sprite_accessory/hair/lizard/curledhorns +/decl/sprite_accessory/horns/lizard/curledhorns name = "Lizard Horns Curled" icon_state = "horns_curled" uid = "acc_hair_una_curledhorns" -/decl/sprite_accessory/hair/lizard/ramhorns +/decl/sprite_accessory/horns/lizard/ramhorns name = "Lizard Horns Ram" icon_state = "horns_ram" uid = "acc_hair_una_ramhorns" -/decl/sprite_accessory/hair/lizard/ramhornsthick +/decl/sprite_accessory/horns/lizard/ramhornsthick name = "Lizard Horns Ram Thick" icon_state = "horns_ram_thick" uid = "acc_hair_una_ramhornsthick" -/decl/sprite_accessory/hair/lizard/doublehorns +/decl/sprite_accessory/horns/lizard/doublehorns name = "Lizard Horns Double" icon_state = "horns_double" uid = "acc_hair_una_doublehorns" -/decl/sprite_accessory/hair/lizard/spinedfrillslong - name = "Lizard Spined Long Frills" - icon_state = "spined_long_frills" - uid = "acc_hair_una_longspinedfrills" - -/decl/sprite_accessory/hair/lizard/spinedfrillsshort - name = "Lizard Spined Short Frills" - icon_state = "spined_short_frills" - uid = "acc_hair_una_shortspinedfrills" - -// FACIAL -/decl/sprite_accessory/facial_hair/lizard +/decl/sprite_accessory/horns/lizard/chin name = "Lizard Horn Chin" - icon = 'mods/species/bayliens/unathi/icons/facial.dmi' icon_state = "facial_chinhorns" - species_allowed = list(SPECIES_LIZARD) - color_blend = ICON_MULTIPLY uid = "acc_fhair_una_chinhorns" -/decl/sprite_accessory/facial_hair/lizard/hornadorns +/decl/sprite_accessory/horns/lizard/hornadorns name = "Lizard Horn Adorns" icon_state = "facial_hornadorns" uid = "acc_fhair_una_adorns" -/decl/sprite_accessory/facial_hair/lizard/spinespikes +/decl/sprite_accessory/horns/lizard/spinespikes name = "Lizard Spine Spikes" icon_state = "facial_spikes" uid = "acc_fhair_una_spinespikes" -/decl/sprite_accessory/facial_hair/lizard/dorsalfrill +/decl/sprite_accessory/frills/lizard + name = "Lizard Frills Aqua" + icon = 'mods/species/bayliens/unathi/icons/frills.dmi' + icon_state = "frills_aqua" + species_allowed = list(SPECIES_LIZARD) + color_blend = ICON_MULTIPLY + accessory_flags = VERY_SHORT + uid = "acc_hair_una_aqua" + +/decl/sprite_accessory/frills/lizard/hood + name = "Lizard Cobra Hood" + icon_state = "cobrahood" + uid = "acc_hair_una_cobra" + +/decl/sprite_accessory/frills/lizard/frills_long + name = "Lizard Frills Long" + icon_state = "frills_long" + uid = "acc_hair_una_longfrills" + +/decl/sprite_accessory/frills/lizard/frills_short + name = "Lizard Frills Short" + icon_state = "frills_short" + uid = "acc_hair_una_shortfrills" + +/decl/sprite_accessory/frills/lizard/sidefrills + name = "Lizard Frills Side" + icon_state = "frills_side" + uid = "acc_hair_una_sidefrills" + +/decl/sprite_accessory/frills/lizard/spinedfrillslong + name = "Lizard Spined Long Frills" + icon_state = "spined_long_frills" + uid = "acc_hair_una_longspinedfrills" + +/decl/sprite_accessory/frills/lizard/spinedfrillsshort + name = "Lizard Spined Short Frills" + icon_state = "spined_short_frills" + uid = "acc_hair_una_shortspinedfrills" + +/decl/sprite_accessory/frills/lizard/dorsalfrill name = "Lizard Frill Dorsal" icon_state = "facial_dorsalfrill" uid = "acc_fhair_una_dorsalfrill" diff --git a/mods/species/bayliens/unathi/icons/cosmetics.dmi b/mods/species/bayliens/unathi/icons/cosmetics.dmi new file mode 100644 index 00000000000..fb049c6d2ec Binary files /dev/null and b/mods/species/bayliens/unathi/icons/cosmetics.dmi differ diff --git a/mods/species/bayliens/unathi/icons/facial.dmi b/mods/species/bayliens/unathi/icons/facial.dmi deleted file mode 100644 index 11ac6ca7926..00000000000 Binary files a/mods/species/bayliens/unathi/icons/facial.dmi and /dev/null differ diff --git a/mods/species/bayliens/unathi/icons/frills.dmi b/mods/species/bayliens/unathi/icons/frills.dmi new file mode 100644 index 00000000000..e113ba90c38 Binary files /dev/null and b/mods/species/bayliens/unathi/icons/frills.dmi differ diff --git a/mods/species/bayliens/unathi/icons/hair.dmi b/mods/species/bayliens/unathi/icons/hair.dmi deleted file mode 100644 index 5422f582410..00000000000 Binary files a/mods/species/bayliens/unathi/icons/hair.dmi and /dev/null differ diff --git a/mods/species/bayliens/unathi/icons/horns.dmi b/mods/species/bayliens/unathi/icons/horns.dmi new file mode 100644 index 00000000000..d1728b439b8 Binary files /dev/null and b/mods/species/bayliens/unathi/icons/horns.dmi differ diff --git a/mods/species/bayliens/unathi/icons/lips.dmi b/mods/species/bayliens/unathi/icons/lips.dmi deleted file mode 100644 index 3cbb5ca90d4..00000000000 Binary files a/mods/species/bayliens/unathi/icons/lips.dmi and /dev/null differ diff --git a/mods/species/neoavians/datum/species_bodytypes.dm b/mods/species/neoavians/datum/species_bodytypes.dm index 112dcd1517e..5fd8b202f78 100644 --- a/mods/species/neoavians/datum/species_bodytypes.dm +++ b/mods/species/neoavians/datum/species_bodytypes.dm @@ -6,7 +6,7 @@ limb_blend = ICON_MULTIPLY bodytype_flag = BODY_FLAG_AVIAN eye_icon = 'mods/species/neoavians/icons/eyes.dmi' - appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_EYE_COLOR + appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR base_color = "#252525" base_eye_color = "#f5c842" mob_size = MOB_SIZE_SMALL @@ -20,8 +20,10 @@ BP_EYES = /obj/item/organ/internal/eyes ) override_limb_types = list(BP_TAIL = /obj/item/organ/external/tail/avian) - default_h_style = /decl/sprite_accessory/hair/avian - base_markings = list(/decl/sprite_accessory/marking/avian = "#454545") + default_sprite_accessories = list( + SAC_HAIR = list(/decl/sprite_accessory/hair/avian = "#252525"), + SAC_MARKINGS = list(/decl/sprite_accessory/marking/avian = "#454545") + ) heat_discomfort_strings = list( "Your feathers prickle in the heat.", diff --git a/mods/species/utility_frames/species_bodytypes.dm b/mods/species/utility_frames/species_bodytypes.dm index c5dc14b5025..57475c6f023 100644 --- a/mods/species/utility_frames/species_bodytypes.dm +++ b/mods/species/utility_frames/species_bodytypes.dm @@ -21,10 +21,12 @@ BP_EYES = /obj/item/organ/internal/eyes, BP_CELL = /obj/item/organ/internal/cell ) - base_markings = list( - /decl/sprite_accessory/marking/frame/plating = "#8888cc", - /decl/sprite_accessory/marking/frame/plating/legs = "#8888cc", - /decl/sprite_accessory/marking/frame/plating/head = "#8888cc" + default_sprite_accessories = list( + SAC_MARKINGS = list( + /decl/sprite_accessory/marking/frame/plating = "#8888cc", + /decl/sprite_accessory/marking/frame/plating/legs = "#8888cc", + /decl/sprite_accessory/marking/frame/plating/head = "#8888cc" + ) ) /decl/bodytype/prosthetic/utility_frame/Initialize() diff --git a/mods/species/vox/_vox.dm b/mods/species/vox/_vox.dm index 9562251d79d..f4671758ba0 100644 --- a/mods/species/vox/_vox.dm +++ b/mods/species/vox/_vox.dm @@ -11,8 +11,8 @@ credits_topics = list("VOX RITUAL DUELS", "NECK MARKINGS", "ANCIENT SUPERCOMPUTERS") /mob/living/carbon/human/vox/Initialize(mapload, species_name, datum/dna/new_dna, decl/bodytype/new_bodytype) - set_hairstyle(/decl/sprite_accessory/hair/vox/short, skip_update = TRUE) - set_hair_colour(COLOR_BEASTY_BROWN, skip_update = TRUE) + SET_HAIR_STYLE(src, /decl/sprite_accessory/hair/vox/short, TRUE) + SET_HAIR_COLOUR(src, COLOR_BEASTY_BROWN, TRUE) species_name = SPECIES_VOX . = ..() diff --git a/mods/species/vox/datum/species_bodytypes.dm b/mods/species/vox/datum/species_bodytypes.dm index ae83e547319..e3cbe948560 100644 --- a/mods/species/vox/datum/species_bodytypes.dm +++ b/mods/species/vox/datum/species_bodytypes.dm @@ -9,12 +9,11 @@ bodytype_flag = BODY_FLAG_VOX limb_blend = ICON_MULTIPLY eye_blend = ICON_MULTIPLY - appearance_flags = HAS_EYE_COLOR | HAS_HAIR_COLOR | HAS_SKIN_COLOR - base_hair_color = "#160900" + appearance_flags = HAS_EYE_COLOR | HAS_SKIN_COLOR base_eye_color = "#d60093" base_color = "#526d29" body_flags = BODY_FLAG_NO_DNA - default_h_style = /decl/sprite_accessory/hair/vox/short + cold_level_1 = 80 cold_level_2 = 50 @@ -39,11 +38,16 @@ BP_STACK = /obj/item/organ/internal/voxstack, BP_HINDTONGUE = /obj/item/organ/internal/hindtongue ) - base_markings = list( - /decl/sprite_accessory/marking/vox/beak = "#bc7d3e", - /decl/sprite_accessory/marking/vox/scutes = "#bc7d3e", - /decl/sprite_accessory/marking/vox/crest = "#bc7d3e", - /decl/sprite_accessory/marking/vox/claws = "#a0a654" + default_sprite_accessories = list( + SAC_HAIR = list( + /decl/sprite_accessory/hair/vox/short = "#160900" + ), + SAC_MARKINGS = list( + /decl/sprite_accessory/marking/vox/beak = "#bc7d3e", + /decl/sprite_accessory/marking/vox/scutes = "#bc7d3e", + /decl/sprite_accessory/marking/vox/crest = "#bc7d3e", + /decl/sprite_accessory/marking/vox/claws = "#a0a654" + ) ) /decl/bodytype/vox/Initialize() @@ -69,13 +73,19 @@ husk_icon = 'mods/species/vox/icons/body/husk.dmi' blood_overlays = 'mods/species/vox/icons/body/blood_overlays.dmi' eye_icon = 'mods/species/vox/icons/body/servitor/eyes.dmi' - base_markings = list( - /decl/sprite_accessory/marking/vox/beak/servitor = "#bc7d3e", - /decl/sprite_accessory/marking/vox/scutes/servitor = "#bc7d3e", - /decl/sprite_accessory/marking/vox/crest/servitor = "#bc7d3e", - /decl/sprite_accessory/marking/vox/claws/servitor = "#a0a654" + + default_sprite_accessories = list( + SAC_HAIR = list( + /decl/sprite_accessory/hair/vox/short/servitor = "#160900" + ), + SAC_MARKINGS = list( + /decl/sprite_accessory/marking/vox/beak/servitor = "#bc7d3e", + /decl/sprite_accessory/marking/vox/scutes/servitor = "#bc7d3e", + /decl/sprite_accessory/marking/vox/crest/servitor = "#bc7d3e", + /decl/sprite_accessory/marking/vox/claws/servitor = "#a0a654" + ) ) - default_h_style = /decl/sprite_accessory/hair/vox/short/servitor + override_limb_types = list( BP_GROIN = /obj/item/organ/external/groin/vox, BP_TAIL = /obj/item/organ/external/tail/vox/servitor @@ -89,13 +99,18 @@ icon_base = 'mods/species/vox/icons/body/stanchion/body.dmi' eye_icon = 'mods/species/vox/icons/body/stanchion/eyes.dmi' icon_template = 'mods/species/vox/icons/body/stanchion/template.dmi' - base_markings = list( - /decl/sprite_accessory/marking/vox/beak/stanchion = "#bc7d3e", - /decl/sprite_accessory/marking/vox/scutes/stanchion = "#bc7d3e", - /decl/sprite_accessory/marking/vox/crest/stanchion = "#bc7d3e", - /decl/sprite_accessory/marking/vox/claws/stanchion = "#a0a654" + default_sprite_accessories = list( + SAC_HAIR = list( + /decl/sprite_accessory/hair/vox/short/stanchion = "#160900" + ), + SAC_MARKINGS = list( + /decl/sprite_accessory/marking/vox/beak/stanchion = "#bc7d3e", + /decl/sprite_accessory/marking/vox/scutes/stanchion = "#bc7d3e", + /decl/sprite_accessory/marking/vox/crest/stanchion = "#bc7d3e", + /decl/sprite_accessory/marking/vox/claws/stanchion = "#a0a654" + ) ) - default_h_style = /decl/sprite_accessory/hair/vox/short/stanchion + override_limb_types = list( BP_GROIN = /obj/item/organ/external/groin/vox, // Commenting this out so that tail validation doesn't try to find a species using this bodytype. diff --git a/nebula.dme b/nebula.dme index 5ee031abf0a..2b110f55b00 100644 --- a/nebula.dme +++ b/nebula.dme @@ -2530,6 +2530,7 @@ #include "code\modules\mob\living\carbon\human\examine.dm" #include "code\modules\mob\living\carbon\human\human.dm" #include "code\modules\mob\living\carbon\human\human_appearance.dm" +#include "code\modules\mob\living\carbon\human\human_appearance_head.dm" #include "code\modules\mob\living\carbon\human\human_attackhand.dm" #include "code\modules\mob\living\carbon\human\human_blood.dm" #include "code\modules\mob\living\carbon\human\human_damage.dm" @@ -3481,9 +3482,13 @@ #include "code\modules\spells\targeted\projectile\projectile.dm" #include "code\modules\spells\targeted\projectile\stuncuff.dm" #include "code\modules\sprite_accessories\_accessory.dm" -#include "code\modules\sprite_accessories\_accessory_facial.dm" -#include "code\modules\sprite_accessories\_accessory_hair.dm" -#include "code\modules\sprite_accessories\_accessory_markings.dm" +#include "code\modules\sprite_accessories\_accessory_category.dm" +#include "code\modules\sprite_accessories\accessory_cosmetics.dm" +#include "code\modules\sprite_accessories\accessory_facial.dm" +#include "code\modules\sprite_accessories\accessory_frills.dm" +#include "code\modules\sprite_accessories\accessory_hair.dm" +#include "code\modules\sprite_accessories\accessory_horns.dm" +#include "code\modules\sprite_accessories\accessory_markings.dm" #include "code\modules\status_conditions\_status.dm" #include "code\modules\status_conditions\_status_markers.dm" #include "code\modules\status_conditions\status_counters_simple.dm"