diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index a801eb17898..86af3b14983 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -36,6 +36,9 @@ CREATE TABLE `characters` ( `facial_red` smallint(4) NOT NULL, `facial_green` smallint(4) NOT NULL, `facial_blue` smallint(4) NOT NULL, + `secondary_facial_red` smallint(4) NOT NULL, + `secondary_facial_green` smallint(4) NOT NULL, + `secondary_facial_blue` smallint(4) NOT NULL, `skin_tone` smallint(4) NOT NULL, `skin_red` smallint(4) NOT NULL, `skin_green` smallint(4) NOT NULL, diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index e4b7e375786..3c417838cfb 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -36,6 +36,9 @@ CREATE TABLE `SS13_characters` ( `facial_red` smallint(4) NOT NULL, `facial_green` smallint(4) NOT NULL, `facial_blue` smallint(4) NOT NULL, + `secondary_facial_red` smallint(4) NOT NULL, + `secondary_facial_green` smallint(4) NOT NULL, + `secondary_facial_blue` smallint(4) NOT NULL, `skin_tone` smallint(4) NOT NULL, `skin_red` smallint(4) NOT NULL, `skin_green` smallint(4) NOT NULL, diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index b252012af18..d7f2a69f190 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -218,10 +218,10 @@ #define BELT_LAYER 15 //Possible make this an overlay of somethign required to wear a belt? #define SUIT_STORE_LAYER 16 #define BACK_LAYER 17 -#define TAIL_LAYER 18 //bs12 specific. this hack is probably gonna come back to haunt me -#define HAIR_LAYER 19 //TODO: make part of head layer? -#define HEAD_ACCESSORY_LAYER 20 -#define FHAIR_LAYER 21 +#define HAIR_LAYER 18 //TODO: make part of head layer? +#define HEAD_ACCESSORY_LAYER 19 +#define FHAIR_LAYER 20 +#define TAIL_LAYER 21 //bs12 specific. this hack is probably gonna come back to haunt me #define FACEMASK_LAYER 22 #define HEAD_LAYER 23 #define COLLAR_LAYER 24 diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm index 6ce30fd0526..002b10cfbba 100644 --- a/code/__DEFINES/mob.dm +++ b/code/__DEFINES/mob.dm @@ -74,8 +74,9 @@ #define APPEARANCE_HAIR_COLOR 32 #define APPEARANCE_FACIAL_HAIR 64 #define APPEARANCE_FACIAL_HAIR_COLOR 128 +#define APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR 128 #define APPEARANCE_EYE_COLOR 256 -#define APPEARANCE_ALL_HAIR APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR +#define APPEARANCE_ALL_HAIR APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR|APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR #define APPEARANCE_HEAD_ACCESSORY 512 #define APPEARANCE_MARKINGS 1024 #define APPEARANCE_BODY_ACCESSORY 2048 diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 893ee78e65e..84e8f820326 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -204,6 +204,12 @@ proc/get_id_photo(var/mob/living/carbon/human/H) facial_s.Blend(rgb(H.r_skin, H.g_skin, H.b_skin, 160), ICON_ADD) else facial_s.Blend(rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial), ICON_ADD) + + if(facial_hair_style.secondary_colour) + var/icon/facial_secondary_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_[facial_hair_style.secondary_colour]_s") + facial_secondary_s.Blend(rgb(head_organ.r_facial_sec, head_organ.g_facial_sec, head_organ.b_facial_sec), ICON_ADD) + facial_s.Blend(facial_secondary_s, ICON_OVERLAY) + face_s.Blend(facial_s, ICON_OVERLAY) //Markings diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index df66ba13a40..c4f84c0b949 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -78,6 +78,11 @@ if(new_facial) M.change_facial_hair_color(hex2num(copytext(new_facial, 2, 4)), hex2num(copytext(new_facial, 4, 6)), hex2num(copytext(new_facial, 6, 8))) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[head_organ.f_style] + if(facial_hair_style.secondary_colour) + new_facial = input("Please select secondary facial hair color.", "Character Generation", rgb(head_organ.r_facial_sec, head_organ.g_facial_sec, head_organ.b_facial_sec)) as null|color + M.change_secondary_facial_hair_color(hex2num(copytext(new_facial, 2, 4)), hex2num(copytext(new_facial, 4, 6)), hex2num(copytext(new_facial, 6, 8))) + //Head accessory. if(head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) var/list/valid_head_accessories = M.generate_valid_head_accessories() diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index aa47e5252ab..61fdfe2607e 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -120,10 +120,13 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/r_hair = 0 //Hair color var/g_hair = 0 //Hair color var/b_hair = 0 //Hair color - var/f_style = "Shaved" //Face hair type - var/r_facial = 0 //Face hair color - var/g_facial = 0 //Face hair color - var/b_facial = 0 //Face hair color + var/f_style = "Shaved" //Facial hair type + var/r_facial = 0 //Facial hair color + var/g_facial = 0 //Facial hair color + var/b_facial = 0 //Facial hair color + var/r_facial_sec = 0 //Secondary facial hair color + var/g_facial_sec = 0 //Secondary facial hair color + var/b_facial_sec = 0 //Secondary facial hair color var/s_tone = 0 //Skin tone var/r_skin = 0 //Skin color var/g_skin = 0 //Skin color @@ -318,6 +321,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "Facial Hair: " dat += "[f_style ? "[f_style]" : "Shaved"]" dat += "Color [color_square(r_facial, g_facial, b_facial)]
" + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] + if(facial_hair_style.secondary_colour) + dat += "Secondary Color [color_square(r_facial_sec, g_facial_sec, b_facial_sec)]
" + if(species != "Machine") dat += "Eyes: " @@ -1256,6 +1263,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts r_hair = 0//hex2num(copytext(new_hair, 2, 4)) g_hair = 0//hex2num(copytext(new_hair, 4, 6)) b_hair = 0//hex2num(copytext(new_hair, 6, 8)) + r_facial = 0 + g_facial = 0 + b_facial = 0 + r_facial_sec = 0 + g_facial_sec = 0 + b_facial_sec = 0 s_tone = 0 @@ -1269,7 +1282,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts body=None;\ tail=None" // No Unathi markings on Tajara - alt_head = null //No alt heads on species that don't have them. + alt_head = "None" //No alt heads on species that don't have them. body_accessory = null //no vulptail on humans damnit @@ -1542,6 +1555,16 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts g_facial = hex2num(copytext(new_facial, 4, 6)) b_facial = hex2num(copytext(new_facial, 6, 8)) + if("secondary_facial") + if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] + if(facial_hair_style.secondary_colour) + var/new_facial = input(user, "Choose your character's secondary facial-hair colour:", "Character Preference", rgb(r_facial_sec, g_facial_sec, b_facial_sec)) as color|null + if(new_facial) + r_facial_sec = hex2num(copytext(new_facial, 2, 4)) + g_facial_sec = hex2num(copytext(new_facial, 4, 6)) + b_facial_sec = hex2num(copytext(new_facial, 6, 8)) + if("f_style") var/list/valid_facialhairstyles = list() for(var/facialhairstyle in facial_hair_styles_list) @@ -2001,6 +2024,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts H.g_facial = g_facial H.b_facial = b_facial + H.r_facial_sec = r_facial_sec + H.g_facial_sec = g_facial_sec + H.b_facial_sec = b_facial_sec + H.h_style = h_style H.f_style = f_style diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index 3a06395ba77..92059ef91ae 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -113,6 +113,9 @@ facial_red, facial_green, facial_blue, + secondary_facial_red, + secondary_facial_green, + secondary_facial_blue, skin_tone, skin_red, skin_green, @@ -183,59 +186,62 @@ r_facial = text2num(query.item[11]) g_facial = text2num(query.item[12]) b_facial = text2num(query.item[13]) - s_tone = text2num(query.item[14]) - r_skin = text2num(query.item[15]) - g_skin = text2num(query.item[16]) - b_skin = text2num(query.item[17]) - m_colours = query.item[18] - r_headacc = text2num(query.item[19]) - g_headacc = text2num(query.item[20]) - b_headacc = text2num(query.item[21]) - h_style = query.item[22] - f_style = query.item[23] - m_styles = query.item[24] - ha_style = query.item[25] - alt_head = query.item[26] - r_eyes = text2num(query.item[27]) - g_eyes = text2num(query.item[28]) - b_eyes = text2num(query.item[29]) - underwear = query.item[30] - undershirt = query.item[31] - backbag = text2num(query.item[32]) - b_type = query.item[33] + r_facial_sec = text2num(query.item[14]) + g_facial_sec = text2num(query.item[15]) + b_facial_sec = text2num(query.item[16]) + s_tone = text2num(query.item[17]) + r_skin = text2num(query.item[18]) + g_skin = text2num(query.item[19]) + b_skin = text2num(query.item[20]) + m_colours = query.item[21] + r_headacc = text2num(query.item[22]) + g_headacc = text2num(query.item[23]) + b_headacc = text2num(query.item[24]) + h_style = query.item[25] + f_style = query.item[26] + m_styles = query.item[27] + ha_style = query.item[28] + alt_head = query.item[29] + r_eyes = text2num(query.item[30]) + g_eyes = text2num(query.item[31]) + b_eyes = text2num(query.item[32]) + underwear = query.item[33] + undershirt = query.item[34] + backbag = text2num(query.item[35]) + b_type = query.item[36] //Jobs - alternate_option = text2num(query.item[34]) - job_support_high = text2num(query.item[35]) - job_support_med = text2num(query.item[36]) - job_support_low = text2num(query.item[37]) - job_medsci_high = text2num(query.item[38]) - job_medsci_med = text2num(query.item[39]) - job_medsci_low = text2num(query.item[40]) - job_engsec_high = text2num(query.item[41]) - job_engsec_med = text2num(query.item[42]) - job_engsec_low = text2num(query.item[43]) - job_karma_high = text2num(query.item[44]) - job_karma_med = text2num(query.item[45]) - job_karma_low = text2num(query.item[46]) + alternate_option = text2num(query.item[37]) + job_support_high = text2num(query.item[38]) + job_support_med = text2num(query.item[39]) + job_support_low = text2num(query.item[40]) + job_medsci_high = text2num(query.item[41]) + job_medsci_med = text2num(query.item[42]) + job_medsci_low = text2num(query.item[43]) + job_engsec_high = text2num(query.item[44]) + job_engsec_med = text2num(query.item[45]) + job_engsec_low = text2num(query.item[46]) + job_karma_high = text2num(query.item[47]) + job_karma_med = text2num(query.item[48]) + job_karma_low = text2num(query.item[49]) //Miscellaneous - flavor_text = query.item[47] - med_record = query.item[48] - sec_record = query.item[49] - gen_record = query.item[50] - disabilities = text2num(query.item[51]) - player_alt_titles = params2list(query.item[52]) - organ_data = params2list(query.item[53]) - rlimb_data = params2list(query.item[54]) - nanotrasen_relation = query.item[55] - speciesprefs = text2num(query.item[56]) + flavor_text = query.item[50] + med_record = query.item[51] + sec_record = query.item[52] + gen_record = query.item[53] + disabilities = text2num(query.item[54]) + player_alt_titles = params2list(query.item[55]) + organ_data = params2list(query.item[56]) + rlimb_data = params2list(query.item[57]) + nanotrasen_relation = query.item[58] + speciesprefs = text2num(query.item[59]) //socks - socks = query.item[57] - body_accessory = query.item[58] - gear = params2list(query.item[59]) + socks = query.item[60] + body_accessory = query.item[61] + gear = params2list(query.item[62]) //Sanitize metadata = sanitize_text(metadata, initial(metadata)) @@ -254,6 +260,9 @@ r_facial = sanitize_integer(r_facial, 0, 255, initial(r_facial)) g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial)) b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial)) + r_facial_sec = sanitize_integer(r_facial_sec, 0, 255, initial(r_facial_sec)) + g_facial_sec = sanitize_integer(g_facial_sec, 0, 255, initial(g_facial_sec)) + b_facial_sec = sanitize_integer(b_facial_sec, 0, 255, initial(b_facial_sec)) s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone)) r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin)) g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin)) @@ -332,6 +341,9 @@ facial_red='[r_facial]', facial_green='[g_facial]', facial_blue='[b_facial]', + secondary_facial_red='[r_facial_sec]', + secondary_facial_green='[g_facial_sec]', + secondary_facial_blue='[b_facial_sec]', skin_tone='[s_tone]', skin_red='[r_skin]', skin_green='[g_skin]', @@ -394,6 +406,7 @@ age, species, language, hair_red, hair_green, hair_blue, facial_red, facial_green, facial_blue, + secondary_facial_blue, secondary_facial_green, secondary_facial_blue, skin_tone, skin_red, skin_green, skin_blue, marking_colours, head_accessory_red, head_accessory_green, head_accessory_blue, @@ -415,6 +428,7 @@ '[age]', '[sql_sanitize_text(species)]', '[sql_sanitize_text(language)]', '[r_hair]', '[g_hair]', '[b_hair]', '[r_facial]', '[g_facial]', '[b_facial]', + '[r_facial_sec]', '[g_facial_sec]', '[b_facial_sec]', '[s_tone]', '[r_skin]', '[g_skin]', '[b_skin]', '[m_colours]', '[r_headacc]', '[g_headacc]', '[b_headacc]', diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 134dbaf4b42..38d177291c4 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -234,6 +234,18 @@ update_fhair() return 1 +/mob/living/carbon/human/proc/change_secondary_facial_hair_color(var/red, var/green, var/blue) + var/obj/item/organ/external/head/H = get_organ("head") + if(red == H.r_facial_sec && green == H.g_facial_sec && blue == H.b_facial_sec) + return + + H.r_facial_sec = red + H.g_facial_sec = green + H.b_facial_sec = blue + + update_fhair() + return 1 + /mob/living/carbon/human/proc/change_head_accessory_color(var/red, var/green, var/blue) var/obj/item/organ/external/head/H = get_organ("head") if(red == H.r_headacc && green == H.g_headacc && blue == H.b_headacc) @@ -271,6 +283,7 @@ b_skin = blue force_update_limbs() + update_body() return 1 /mob/living/carbon/human/proc/change_skin_tone(var/tone) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index a1f7058348a..9a48fcc8593 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1586,6 +1586,9 @@ m_styles = initial(m_styles) //Wipes out markings, setting them all to "None". m_colours = initial(m_styles) //Defaults colour to #00000 for all markings. + H.alt_head = "None" + H.ha_style = "None" + body_accessory = null if(!dna) dna = new /datum/dna(null) diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 7b0309dc1ac..485ee4b6844 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -172,7 +172,7 @@ flags = HAS_LIPS clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS | HAS_TAIL_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING | HAS_FUR + bodyflags = FEET_PADDED | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS | HAS_TAIL_MARKINGS | HAS_SKIN_COLOR | HAS_FUR dietflags = DIET_OMNI reagent_tag = PROCESS_ORG flesh_color = "#966464" diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 35f99724e60..e8f5f96751c 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -470,12 +470,12 @@ var/global/list/damage_icon_parts = list() overlays_standing[FHAIR_LAYER] = null var/obj/item/organ/external/head/head_organ = get_organ("head") - if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED) ) + if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED)) if(update_icons) update_icons() return //masks and helmets can obscure our facial hair, unless we're a synthetic - if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR))) + if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR))) if(update_icons) update_icons() return @@ -491,6 +491,12 @@ var/global/list/damage_icon_parts = list() facial_s.Blend(rgb(r_skin, g_skin, b_skin, 160), ICON_AND) else if(facial_hair_style.do_colouration) facial_s.Blend(rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial), ICON_ADD) + + if(facial_hair_style.secondary_colour) + var/icon/facial_secondary_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_[facial_hair_style.secondary_colour]_s") + facial_secondary_s.Blend(rgb(head_organ.r_facial_sec, head_organ.g_facial_sec, head_organ.b_facial_sec), ICON_ADD) + facial_s.Blend(facial_secondary_s, ICON_OVERLAY) + face_standing.Blend(facial_s, ICON_OVERLAY) else //warning("Invalid f_style for [species.name]: [f_style]") @@ -1118,9 +1124,9 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/proc/update_tail_layer(var/update_icons=1) overlays_standing[TAIL_UNDERLIMBS_LAYER] = null // SEW direction icons, overlayed by LIMBS_LAYER. - overlays_standing[TAIL_LAYER] = null // This will be one of two things: - // If the species' tail is overlapped by limbs, this will be only the N direction icon so tails can still appear on the outside of uniforms and such. - // Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. + overlays_standing[TAIL_LAYER] = null /* This will be one of two things: + If the species' tail is overlapped by limbs, this will be only the N direction icon so tails can still appear on the outside of uniforms and such. + Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. */ var/list/marking_styles = params2list(m_styles) var/icon/tail_marking_icon @@ -1143,20 +1149,20 @@ var/global/list/damage_icon_parts = list() if(species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "accessory_none_s") - under.Insert(new/icon(accessory_s,dir=SOUTH),dir=SOUTH) - under.Insert(new/icon(accessory_s,dir=EAST),dir=EAST) - under.Insert(new/icon(accessory_s,dir=WEST),dir=WEST) + under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH) + under.Insert(new/icon(accessory_s, dir=EAST), dir=EAST) + under.Insert(new/icon(accessory_s, dir=WEST), dir=WEST) - overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) // Creates a blank icon, and copies accessory_s' north direction sprite into it // before passing that to the tail layer that overlays uniforms and such. - var/icon/over = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon state" = "accessory_none_s") - over.Insert(new/icon(accessory_s,dir=NORTH),dir=NORTH) + var/icon/over = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "accessory_none_s") + over.Insert(new/icon(accessory_s, dir=NORTH), dir=NORTH) - overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. - overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else if(species.tail && species.bodyflags & HAS_TAIL) //no tailless tajaran if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) @@ -1172,15 +1178,15 @@ var/global/list/damage_icon_parts = list() under.Insert(new/icon(tail_s, dir=EAST), dir=EAST) under.Insert(new/icon(tail_s, dir=WEST), dir=WEST) - overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under) + overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under) // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "blank") over.Insert(new/icon(tail_s, dir=NORTH), dir=NORTH) - overlays_standing[TAIL_LAYER] = image(over) + overlays_standing[TAIL_LAYER] = image(over) else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. - overlays_standing[TAIL_LAYER] = image(tail_s) + overlays_standing[TAIL_LAYER] = image(tail_s) if(update_icons) update_icons() @@ -1188,9 +1194,9 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/proc/start_tail_wagging(var/update_icons=1) overlays_standing[TAIL_UNDERLIMBS_LAYER] = null // SEW direction icons, overlayed by LIMBS_LAYER. - overlays_standing[TAIL_LAYER] = null // This will be one of two things: - // If the species' tail is overlapped by limbs, this will be only the N direction icon so tails can still appear on the outside of uniforms and such. - // Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. + overlays_standing[TAIL_LAYER] = null /* This will be one of two things: + If the species' tail is overlapped by limbs, this will be only the N direction icon so tails can still appear on the outside of uniforms and such. + Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. */ var/list/marking_styles = params2list(m_styles) var/icon/tail_marking_icon @@ -1211,24 +1217,24 @@ var/global/list/damage_icon_parts = list() accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) if(species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. - var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "vulpkanin_tail_delay") + var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") if(body_accessory.allowed_species && (species.name in body_accessory.allowed_species)) under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") - under.Insert(accessory_s, dir=SOUTH) - under.Insert(accessory_s, dir=EAST) - under.Insert(accessory_s, dir=WEST) + under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH) + under.Insert(new/icon(accessory_s, dir=EAST), dir=EAST) + under.Insert(new/icon(accessory_s, dir=WEST), dir=WEST) - overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. - var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "vulpkanin_tail_delay") + var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") if(body_accessory.allowed_species && (species.name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") - over.Insert(accessory_s, dir=NORTH) + over.Insert(new/icon(accessory_s, dir=NORTH), dir=NORTH) - overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. - overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else if(species.tail && species.bodyflags & HAS_TAIL) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]w_s") @@ -1239,19 +1245,19 @@ var/global/list/damage_icon_parts = list() if(species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") - under.Insert(tailw_s, dir=SOUTH) - under.Insert(tailw_s, dir=EAST) - under.Insert(tailw_s, dir=WEST) + under.Insert(new/icon(tailw_s, dir=SOUTH), dir=SOUTH) + under.Insert(new/icon(tailw_s, dir=EAST), dir=EAST) + under.Insert(new/icon(tailw_s, dir=WEST), dir=WEST) - overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under) + overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under) // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") - over.Insert(tailw_s, dir=NORTH) + over.Insert(new/icon(tailw_s, dir=NORTH), dir=NORTH) - overlays_standing[TAIL_LAYER] = image(over) + overlays_standing[TAIL_LAYER] = image(over) else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. - overlays_standing[TAIL_LAYER] = image(tailw_s) + overlays_standing[TAIL_LAYER] = image(tailw_s) if(update_icons) update_icons() diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index e5fa2656436..bb9e3f501a0 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -338,6 +338,12 @@ facial_s.Blend(rgb(r_skin, g_skin, b_skin, 160), ICON_ADD) else facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) + + if(facial_hair_style.secondary_colour) + var/icon/facial_secondary_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_[facial_hair_style.secondary_colour]_s") + facial_secondary_s.Blend(rgb(r_facial_sec, g_facial_sec, b_facial_sec), ICON_ADD) + facial_s.Blend(facial_secondary_s, ICON_OVERLAY) + face_s.Blend(facial_s, ICON_OVERLAY) var/icon/underwear_s = null diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 83b69c1a37b..dd2540c7d50 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -47,6 +47,7 @@ var/list/heads_allowed = null //Specifies which, if any, alt heads a head marking, hairstyle or facial hair style is compatible with. var/list/tails_allowed = null //Specifies which, if any, tails a tail marking is compatible with. var/marking_location //Specifies which bodypart a body marking is located on. + var/secondary_colour = null //If exists, there's a secondary colour to that hair style and the secondary colour's icon state's suffix is equal to this. // Whether or not the accessory can be affected by colouration var/do_colouration = 1 @@ -1107,6 +1108,12 @@ species_allowed = list("Unathi") gender = NEUTER + una_frills_aquatic + name = "Aquatic Frills" + icon_state = "soghun_aquaticfrills" + species_allowed = list("Unathi") + gender = NEUTER + una_frills_long name = "Long Frills" icon_state = "soghun_longfrills" @@ -1119,22 +1126,25 @@ species_allowed = list("Unathi") gender = NEUTER + una_frills_webbed_aquatic + name = "Aquatic Webbed Frills" + icon_state = "soghun_aquaticfrills" + species_allowed = list("Unathi") + secondary_colour = "webbing" + gender = NEUTER + una_frills_webbed_long name = "Long Webbed Frills" - icon_state = "soghun_longfrills_webbed" + icon_state = "soghun_longfrills" species_allowed = list("Unathi") + secondary_colour = "webbing" gender = NEUTER una_frills_webbed_short name = "Short Webbed Frills" - icon_state = "soghun_shortfrills_webbed" - species_allowed = list("Unathi") - gender = NEUTER - - una_frills_webbed_aquatic - name = "Aquatic Frills" - icon_state = "soghun_aquaticfrills_webbed" + icon_state = "soghun_shortfrills" species_allowed = list("Unathi") + secondary_colour = "webbing" gender = NEUTER @@ -1968,10 +1978,20 @@ species_allowed = list("Unathi", "Tajaran", "Vulpkanin") icon_state = "markings_tiger" -/datum/sprite_accessory/body_markings/tigerhead - name = "Tiger Body and Head" - species_allowed = list("Unathi", "Tajaran", "Vulpkanin") - icon_state = "markings_tigerhead" +/datum/sprite_accessory/body_markings/tigerhead_taj + name = "Tajaran Tiger Body and Head" + species_allowed = list("Tajaran") + icon_state = "markings_tigerhead_taj" + +/datum/sprite_accessory/body_markings/tigerhead_vulp + name = "Vulpkanin Tiger Body and Head" + species_allowed = list("Vulpkanin") + icon_state = "markings_tigerhead_vulp" + +/datum/sprite_accessory/body_markings/tigerhead_una + name = "Unathi Tiger Body and Head" + species_allowed = list("Unathi") + icon_state = "markings_tigerhead_una" /datum/sprite_accessory/body_markings/tigerheadface_taj name = "Tajaran Tiger Body, Head and Face" diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 11e702e97a0..69d27247c37 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -103,6 +103,16 @@ if(owner.change_facial_hair_color(r_facial, g_facial, b_facial)) update_dna() return 1 + if(href_list["secondary_facial_hair_color"]) + if(can_change(APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR)) + var/new_facial = input("Please select secondary facial hair color.", "Secondary Facial Hair Color", rgb(head_organ.r_facial_sec, head_organ.g_facial_sec, head_organ.b_facial_sec)) as color|null + if(new_facial && can_still_topic(state)) + var/r_facial_sec = hex2num(copytext(new_facial, 2, 4)) + var/g_facial_sec = hex2num(copytext(new_facial, 4, 6)) + var/b_facial_sec = hex2num(copytext(new_facial, 6, 8)) + if(owner.change_secondary_facial_hair_color(r_facial_sec, g_facial_sec, b_facial_sec)) + update_dna() + return 1 if(href_list["eye_color"]) if(can_change(APPEARANCE_EYE_COLOR)) var/new_eyes = input("Please select eye color.", "Eye Color", rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) as color|null @@ -276,6 +286,7 @@ data["change_head_accessory_color"] = can_change_head_accessory() data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) + data["change_secondary_facial_hair_color"] = can_change(APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR) data["change_head_marking_color"] = can_change_markings("head") data["change_body_marking_color"] = can_change_markings("body") data["change_tail_marking_color"] = can_change_markings("tail") @@ -314,16 +325,12 @@ if(location == "tail") marking_flag = HAS_TAIL_MARKINGS - - return owner && (flags & APPEARANCE_MARKINGS) && (body_flags & marking_flag) /datum/nano_module/appearance_changer/proc/can_change_body_accessory() return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.species.bodyflags & HAS_TAIL) /datum/nano_module/appearance_changer/proc/can_change_alt_head() - if(owner.species.bodyflags & HAS_ALT_HEADS) - to_chat(world, "has alt heads") return owner && (flags & APPEARANCE_ALT_HEAD) && (owner.species.bodyflags & HAS_ALT_HEADS) /datum/nano_module/appearance_changer/proc/cut_and_generate_data() diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index 61baafa1b62..37253e3e562 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -158,6 +158,9 @@ var/r_facial = 0 var/g_facial = 0 var/b_facial = 0 + var/r_facial_sec = 0 + var/g_facial_sec = 0 + var/b_facial_sec = 0 var/f_style = "Shaved" /obj/item/organ/external/head/remove() diff --git a/icons/mob/body_accessory.dmi b/icons/mob/body_accessory.dmi index d3e11579d8e..bf3016b404a 100644 Binary files a/icons/mob/body_accessory.dmi and b/icons/mob/body_accessory.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 5d4144f35fd..e082f7060a0 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl index 060e4df88f8..b983135380b 100644 --- a/nano/templates/appearance_changer.tmpl +++ b/nano/templates/appearance_changer.tmpl @@ -46,6 +46,9 @@ {{/if}} {{if data.change_facial_hair_color}} {{:helper.link('Change facial hair color', null, { 'facial_hair_color' : 1})}} + {{/if}} + {{if data.change_secondary_facial_hair_color}} + {{:helper.link('Change secondary facial hair color', null, { 'secondary_facial_hair_color' : 1})}} {{/if}} {{if data.change_head_marking_color}} {{:helper.link('Change head marking color', null, { 'head_marking_color' : 1})}}