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})}}