diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql
index b0e03f68efa..c33487d0394 100644
--- a/SQL/paradise_schema.sql
+++ b/SQL/paradise_schema.sql
@@ -40,8 +40,16 @@ CREATE TABLE `characters` (
`skin_red` smallint(4) NOT NULL,
`skin_green` smallint(4) NOT NULL,
`skin_blue` smallint(4) NOT NULL,
+ `markings_red` smallint(4) NOT NULL,
+ `markings_green` smallint(4) NOT NULL,
+ `markings_blue` smallint(4) NOT NULL,
+ `head_accessory_red` smallint(4) NOT NULL,
+ `head_accessory_green` smallint(4) NOT NULL,
+ `head_accessory_blue` smallint(4) NOT NULL,
`hair_style_name` varchar(45) NOT NULL,
`facial_style_name` varchar(45) NOT NULL,
+ `marking_style_name` varchar(45) NOT NULL,
+ `head_accessory_style_name` varchar(45) NOT NULL,
`eyes_red` smallint(4) NOT NULL,
`eyes_green` smallint(4) NOT NULL,
`eyes_blue` smallint(4) NOT NULL,
diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql
index 567da99c300..d4d75838020 100644
--- a/SQL/paradise_schema_prefixed.sql
+++ b/SQL/paradise_schema_prefixed.sql
@@ -40,8 +40,16 @@ CREATE TABLE `SS13_characters` (
`skin_red` smallint(4) NOT NULL,
`skin_green` smallint(4) NOT NULL,
`skin_blue` smallint(4) NOT NULL,
+ `markings_red` smallint(4) NOT NULL,
+ `markings_green` smallint(4) NOT NULL,
+ `markings_blue` smallint(4) NOT NULL,
+ `head_accessory_red` smallint(4) NOT NULL,
+ `head_accessory_green` smallint(4) NOT NULL,
+ `head_accessory_blue` smallint(4) NOT NULL,
`hair_style_name` varchar(45) NOT NULL,
`facial_style_name` varchar(45) NOT NULL,
+ `marking_style_name` varchar(45) NOT NULL,
+ `head_accessory_style_name` varchar(45) NOT NULL,
`eyes_red` smallint(4) NOT NULL,
`eyes_green` smallint(4) NOT NULL,
`eyes_blue` smallint(4) NOT NULL,
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 20930f1cdb8..521349b02af 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -55,14 +55,16 @@
#define HAS_SOCKS 4
//Species Body Flags
-#define FEET_CLAWS 1
-#define FEET_PADDED 2
-#define FEET_NOSLIP 4
-#define HAS_TAIL 8
-#define HAS_SKIN_TONE 16
-#define HAS_SKIN_COLOR 32
-#define TAIL_WAGGING 64
-#define NO_EYES 128
+#define FEET_CLAWS 1
+#define FEET_PADDED 2
+#define FEET_NOSLIP 4
+#define HAS_HEAD_ACCESSORY 8
+#define HAS_TAIL 16
+#define HAS_SKIN_TONE 32
+#define HAS_SKIN_COLOR 64
+#define HAS_MARKINGS 128
+#define TAIL_WAGGING 256
+#define NO_EYES 512
//Species Diet Flags
#define DIET_CARN 1
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 500553e1f28..e9a71917425 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -4,6 +4,10 @@
//////////////////////////
/proc/makeDatumRefLists()
+ //markings
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, marking_styles_list)
+ //head accessory
+ init_sprite_accessory_subtypes(/datum/sprite_accessory/head_accessory, head_accessory_styles_list)
//hair
init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, hair_styles_list, hair_styles_male_list, hair_styles_female_list)
//facial hair
diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm
index 516ae5630f9..0cf3a0d2853 100644
--- a/code/_globalvars/lists/flavor_misc.dm
+++ b/code/_globalvars/lists/flavor_misc.dm
@@ -1,4 +1,8 @@
//Preferences stuff
+ //Head accessory styles
+var/global/list/head_accessory_styles_list = list() //stores /datum/sprite_accessory/head_accessory indexed by name
+ //Marking styles
+var/global/list/marking_styles_list = list() //stores /datum/sprite_accessory/horns indexed by name
//Hairstyles
var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name
var/global/list/hair_styles_male_list = list()
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 7f0e58d3bbb..41019d29356 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -173,12 +173,30 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
hair_s.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD)
eyes_s.Blend(hair_s, ICON_OVERLAY)
+ //Head Accessory
+ if(H.species.bodyflags & HAS_HEAD_ACCESSORY)
+ var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[H.ha_style]
+ if(head_accessory_style && head_accessory_style.species_allowed)
+ var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s")
+ head_accessory_s.Blend(rgb(H.r_headacc, H.g_headacc, H.b_headacc), ICON_ADD)
+ eyes_s.Blend(head_accessory_s, ICON_OVERLAY)
+
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style]
- if(facial_hair_style)
+ if(facial_hair_style && facial_hair_style.species_allowed)
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD)
eyes_s.Blend(facial_s, ICON_OVERLAY)
+ //Markings
+ if(H.species.bodyflags & HAS_MARKINGS)
+ var/datum/sprite_accessory/marking_style = marking_styles_list[H.m_style]
+ if(marking_style && marking_style.species_allowed)
+ var/icon/markings_s = new/icon("icon" = marking_style.icon, "icon_state" = "[marking_style.icon_state]_s")
+ markings_s.Blend(rgb(H.r_markings, H.g_markings, H.b_markings), ICON_ADD)
+ eyes_s.Blend(markings_s, ICON_OVERLAY)
+
+ preview_icon.Blend(eyes_s, ICON_OVERLAY)
+
var/icon/clothes_s = null
switch(H.mind.assigned_role)
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index 0687b41e691..4ca8ece26e0 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -17,23 +17,32 @@
#define DNA_HARD_BOUNDS list(1,3490,3500,4095)
// UI Indices (can change to mutblock style, if desired)
-#define DNA_UI_HAIR_R 1
-#define DNA_UI_HAIR_G 2
-#define DNA_UI_HAIR_B 3
-#define DNA_UI_BEARD_R 4
-#define DNA_UI_BEARD_G 5
-#define DNA_UI_BEARD_B 6
-#define DNA_UI_SKIN_TONE 7
-#define DNA_UI_SKIN_R 8
-#define DNA_UI_SKIN_G 9
-#define DNA_UI_SKIN_B 10
-#define DNA_UI_EYES_R 11
-#define DNA_UI_EYES_G 12
-#define DNA_UI_EYES_B 13
-#define DNA_UI_GENDER 14
-#define DNA_UI_BEARD_STYLE 15
-#define DNA_UI_HAIR_STYLE 16
-#define DNA_UI_LENGTH 16 // Update this when you add something, or you WILL break shit.
+#define DNA_UI_HAIR_R 1
+#define DNA_UI_HAIR_G 2
+#define DNA_UI_HAIR_B 3
+#define DNA_UI_BEARD_R 4
+#define DNA_UI_BEARD_G 5
+#define DNA_UI_BEARD_B 6
+#define DNA_UI_SKIN_TONE 7
+#define DNA_UI_SKIN_R 8
+#define DNA_UI_SKIN_G 9
+#define DNA_UI_SKIN_B 10
+#define DNA_UI_HACC_R 11
+#define DNA_UI_HACC_G 12
+#define DNA_UI_HACC_B 13
+#define DNA_UI_MARK_R 14
+#define DNA_UI_MARK_G 15
+#define DNA_UI_MARK_B 16
+#define DNA_UI_EYES_R 17
+#define DNA_UI_EYES_G 18
+#define DNA_UI_EYES_B 19
+#define DNA_UI_GENDER 20
+#define DNA_UI_BEARD_STYLE 21
+#define DNA_UI_HAIR_STYLE 22
+/*#define DNA_UI_BACC_STYLE 23*/
+#define DNA_UI_HACC_STYLE 23
+#define DNA_UI_MARK_STYLE 24
+#define DNA_UI_LENGTH 24 // Update this when you add something, or you WILL break shit.
#define DNA_SE_LENGTH 55 // Was STRUCDNASIZE, size 27. 15 new blocks added = 42, plus room to grow.
@@ -133,28 +142,55 @@ var/global/list/bad_blocks[0]
character.f_style = "Shaved"
var/beard = facial_hair_styles_list.Find(character.f_style)
- SetUIValueRange(DNA_UI_HAIR_R, character.r_hair, 255, 1)
- SetUIValueRange(DNA_UI_HAIR_G, character.g_hair, 255, 1)
- SetUIValueRange(DNA_UI_HAIR_B, character.b_hair, 255, 1)
+ // Head Accessory
+ if(!character.ha_style)
+ character.ha_style = "None"
+ var/headacc = head_accessory_styles_list.Find(character.ha_style)
- SetUIValueRange(DNA_UI_BEARD_R, character.r_facial, 255, 1)
- SetUIValueRange(DNA_UI_BEARD_G, character.g_facial, 255, 1)
- SetUIValueRange(DNA_UI_BEARD_B, character.b_facial, 255, 1)
+ /*// Body Accessory
+ if(!character.body_accessory)
+ character.body_accessory = null
+ var/bodyacc = character.body_accessory*/
- SetUIValueRange(DNA_UI_EYES_R, character.r_eyes, 255, 1)
- SetUIValueRange(DNA_UI_EYES_G, character.g_eyes, 255, 1)
- SetUIValueRange(DNA_UI_EYES_B, character.b_eyes, 255, 1)
+ // Markings
+ if(!character.m_style)
+ character.m_style = "None"
+ var/marks = marking_styles_list.Find(character.m_style)
- SetUIValueRange(DNA_UI_SKIN_R, character.r_skin, 255, 1)
- SetUIValueRange(DNA_UI_SKIN_G, character.g_skin, 255, 1)
- SetUIValueRange(DNA_UI_SKIN_B, character.b_skin, 255, 1)
+ SetUIValueRange(DNA_UI_HAIR_R, character.r_hair, 255, 1)
+ SetUIValueRange(DNA_UI_HAIR_G, character.g_hair, 255, 1)
+ SetUIValueRange(DNA_UI_HAIR_B, character.b_hair, 255, 1)
- SetUIValueRange(DNA_UI_SKIN_TONE, 35-character.s_tone, 220, 1) // Value can be negative.
+ SetUIValueRange(DNA_UI_BEARD_R, character.r_facial, 255, 1)
+ SetUIValueRange(DNA_UI_BEARD_G, character.g_facial, 255, 1)
+ SetUIValueRange(DNA_UI_BEARD_B, character.b_facial, 255, 1)
- SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1)
+ SetUIValueRange(DNA_UI_EYES_R, character.r_eyes, 255, 1)
+ SetUIValueRange(DNA_UI_EYES_G, character.g_eyes, 255, 1)
+ SetUIValueRange(DNA_UI_EYES_B, character.b_eyes, 255, 1)
+
+ SetUIValueRange(DNA_UI_SKIN_R, character.r_skin, 255, 1)
+ SetUIValueRange(DNA_UI_SKIN_G, character.g_skin, 255, 1)
+ SetUIValueRange(DNA_UI_SKIN_B, character.b_skin, 255, 1)
+
+ SetUIValueRange(DNA_UI_HACC_R, character.r_headacc, 255, 1)
+ SetUIValueRange(DNA_UI_HACC_G, character.g_headacc, 255, 1)
+ SetUIValueRange(DNA_UI_HACC_B, character.b_headacc, 255, 1)
+
+ SetUIValueRange(DNA_UI_MARK_R, character.r_markings, 255, 1)
+ SetUIValueRange(DNA_UI_MARK_G, character.g_markings, 255, 1)
+ SetUIValueRange(DNA_UI_MARK_B, character.b_markings, 255, 1)
+
+ SetUIValueRange(DNA_UI_SKIN_TONE, 35-character.s_tone, 220, 1) // Value can be negative.
+
+ SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1)
+
+ SetUIValueRange(DNA_UI_HAIR_STYLE, hair, hair_styles_list.len, 1)
+ SetUIValueRange(DNA_UI_BEARD_STYLE, beard, facial_hair_styles_list.len, 1)
+ /*SetUIValueRange(DNA_UI_BACC_STYLE, bodyacc, facial_hair_styles_list.len, 1)*/
+ SetUIValueRange(DNA_UI_HACC_STYLE, headacc, head_accessory_styles_list.len, 1)
+ SetUIValueRange(DNA_UI_MARK_STYLE, marks, marking_styles_list.len, 1)
- SetUIValueRange(DNA_UI_HAIR_STYLE, hair, hair_styles_list.len, 1)
- SetUIValueRange(DNA_UI_BEARD_STYLE, beard, facial_hair_styles_list.len,1)
UpdateUI()
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index 06973f6f4e6..4aa0453a52d 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -131,21 +131,31 @@
src.dna.UpdateUI()
dna.check_integrity()
var/mob/living/carbon/human/H = src
- H.r_hair = dna.GetUIValueRange(DNA_UI_HAIR_R, 255)
- H.g_hair = dna.GetUIValueRange(DNA_UI_HAIR_G, 255)
- H.b_hair = dna.GetUIValueRange(DNA_UI_HAIR_B, 255)
+ H.r_hair = dna.GetUIValueRange(DNA_UI_HAIR_R, 255)
+ H.g_hair = dna.GetUIValueRange(DNA_UI_HAIR_G, 255)
+ H.b_hair = dna.GetUIValueRange(DNA_UI_HAIR_B, 255)
- H.r_facial = dna.GetUIValueRange(DNA_UI_BEARD_R, 255)
- H.g_facial = dna.GetUIValueRange(DNA_UI_BEARD_G, 255)
- H.b_facial = dna.GetUIValueRange(DNA_UI_BEARD_B, 255)
+ H.r_facial = dna.GetUIValueRange(DNA_UI_BEARD_R, 255)
+ H.g_facial = dna.GetUIValueRange(DNA_UI_BEARD_G, 255)
+ H.b_facial = dna.GetUIValueRange(DNA_UI_BEARD_B, 255)
+
+ H.r_skin = dna.GetUIValueRange(DNA_UI_SKIN_R, 255)
+ H.g_skin = dna.GetUIValueRange(DNA_UI_SKIN_G, 255)
+ H.b_skin = dna.GetUIValueRange(DNA_UI_SKIN_B, 255)
+
+ H.r_eyes = dna.GetUIValueRange(DNA_UI_EYES_R, 255)
+ H.g_eyes = dna.GetUIValueRange(DNA_UI_EYES_G, 255)
+ H.b_eyes = dna.GetUIValueRange(DNA_UI_EYES_B, 255)
+
+ H.r_headacc = dna.GetUIValueRange(DNA_UI_HACC_R, 255)
+ H.g_headacc = dna.GetUIValueRange(DNA_UI_HACC_G, 255)
+ H.b_headacc = dna.GetUIValueRange(DNA_UI_HACC_B, 255)
+
+ H.r_markings = dna.GetUIValueRange(DNA_UI_MARK_R, 255)
+ H.g_markings = dna.GetUIValueRange(DNA_UI_MARK_G, 255)
+ H.b_markings = dna.GetUIValueRange(DNA_UI_MARK_B, 255)
- H.r_skin = dna.GetUIValueRange(DNA_UI_SKIN_R, 255)
- H.g_skin = dna.GetUIValueRange(DNA_UI_SKIN_G, 255)
- H.b_skin = dna.GetUIValueRange(DNA_UI_SKIN_B, 255)
- H.r_eyes = dna.GetUIValueRange(DNA_UI_EYES_R, 255)
- H.g_eyes = dna.GetUIValueRange(DNA_UI_EYES_G, 255)
- H.b_eyes = dna.GetUIValueRange(DNA_UI_EYES_B, 255)
H.update_eyes()
H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative.
@@ -165,9 +175,22 @@
if((0 < beard) && (beard <= facial_hair_styles_list.len))
H.f_style = facial_hair_styles_list[beard]
+ //Head Accessories
+ var/headacc = dna.GetUIValueRange(DNA_UI_HACC_STYLE,head_accessory_styles_list.len)
+ if((0 < headacc) && (headacc <= head_accessory_styles_list.len))
+ H.ha_style = head_accessory_styles_list[headacc]
+
+ //Markings
+ var/marks = dna.GetUIValueRange(DNA_UI_MARK_STYLE,marking_styles_list.len)
+ if((0 < marks) && (marks <= marking_styles_list.len))
+ H.m_style = marking_styles_list[marks]
+
H.force_update_limbs()
H.update_eyes()
H.update_hair()
+ H.update_fhair()
+ H.update_markings()
+ H.update_head_accessory()
return 1
else
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index 974879a0553..4ca71490dc0 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -70,6 +70,7 @@
H.update_inv_wear_suit()
H.update_inv_head()
H.update_hair()
+ H.update_fhair()
if(blood_on_castoff)
var/turf/simulated/T = get_turf(H)
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index 587b9ad1af5..2adbf74726c 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -334,6 +334,7 @@ var/global/list/multiverse = list()
domutcheck(M, null)
M.update_body()
M.update_hair()
+ M.update_fhair()
equip_copy(M)
diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm
index 08cc4086a9a..409679d4ac3 100644
--- a/code/game/objects/items/weapons/cosmetics.dm
+++ b/code/game/objects/items/weapons/cosmetics.dm
@@ -105,7 +105,7 @@
user.visible_message("[user] shaves his facial hair clean with the [src].", \
"You finish shaving with the [src]. Fast and clean!")
H.f_style = "Shaved"
- H.update_hair()
+ H.update_fhair()
playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1)
else
var/turf/user_loc = user.loc
@@ -117,7 +117,7 @@
user.visible_message("[user] shaves off [H]'s facial hair with \the [src].", \
"You shave [H]'s facial hair clean off.")
H.f_style = "Shaved"
- H.update_hair()
+ H.update_fhair()
playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1)
if(user.zone_sel.selecting == "head")
if(!get_location_accessible(H, "head"))
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index bc28c88ee2f..d82d029a530 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -97,6 +97,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
var/undershirt = "Nude" //undershirt type
var/socks = "Nude" //socks type
var/backbag = 2 //backpack type
+ var/ha_style = "None" //Head accessory style
+ var/r_headacc = 0 //Head accessory colour
+ var/g_headacc = 0 //Head accessory colour
+ var/b_headacc = 0 //Head accessory colour
+ var/m_style = "None" //Marking style
+ var/r_markings = 0 //Marking colour
+ var/g_markings = 0 //Marking colour
+ var/b_markings = 0 //Marking colour
var/h_style = "Bald" //Hair type
var/r_hair = 0 //Hair color
var/g_hair = 0 //Hair color
@@ -341,6 +349,18 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "[TextPreview(flavor_text)]...
"
dat += "
"
+ if((species in list("Unathi", "Vulpkanin", "Tajaran"))) //Species that have head accessories.
+ var/headaccessoryname = "Head Accessory"
+ if(species == "Unathi")
+ headaccessoryname = "Horns"
+ dat += "
[headaccessoryname]
"
+ dat += "Change Color "
+ dat += "Style: [ha_style]
"
+
+ dat += "
Body Markings
"
+ dat += "Change Color "
+ dat += "
Style: [m_style]
"
+
var/hairname = "Hair"
if(species == "Machine")
hairname = "Frame Color"
@@ -1112,6 +1132,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
s_tone = 0
+ ha_style = "None" // No Vulp ears on Unathi
+ m_style = "None" // No Unathi markings on Tajara
+
body_accessory = null //no vulpatail on humans damnit
if("speciesprefs")//oldvox code
speciesprefs = !speciesprefs
@@ -1172,6 +1195,52 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if(new_h_style)
h_style = new_h_style
+ if("headaccessory")
+ if((species in list("Unathi", "Vulpkanin", "Tajaran"))) // Species with head accessories
+ var/input = "Choose the colour of your your character's head accessory:"
+ var/new_head_accessory = input(user, input, "Character Preference", rgb(r_headacc, g_headacc, b_headacc)) as color|null
+ if(new_head_accessory)
+ r_headacc = hex2num(copytext(new_head_accessory, 2, 4))
+ g_headacc = hex2num(copytext(new_head_accessory, 4, 6))
+ b_headacc = hex2num(copytext(new_head_accessory, 6, 8))
+
+ if("ha_style")
+ if((species in list("Unathi", "Vulpkanin", "Tajaran"))) // Species with head accessories
+ var/list/valid_head_accessory_styles = list()
+ for(var/head_accessory_style in head_accessory_styles_list)
+ var/datum/sprite_accessory/H = head_accessory_styles_list[head_accessory_style]
+ if( !(species in H.species_allowed))
+ continue
+
+ valid_head_accessory_styles[head_accessory_style] = head_accessory_styles_list[head_accessory_style]
+
+ var/new_head_accessory_style = input(user, "Choose the style of your character's head accessory:", "Character Preference") as null|anything in valid_head_accessory_styles
+ if(new_head_accessory_style)
+ ha_style = new_head_accessory_style
+
+ if("markings")
+ if((species in list("Unathi", "Vulpkanin", "Tajaran"))) // Species with markings
+ var/input = "Choose the colour of your your character's body markings:"
+ var/new_markings = input(user, input, "Character Preference", rgb(r_markings, g_markings, b_markings)) as color|null
+ if(new_markings)
+ r_markings = hex2num(copytext(new_markings, 2, 4))
+ g_markings = hex2num(copytext(new_markings, 4, 6))
+ b_markings = hex2num(copytext(new_markings, 6, 8))
+
+ if("m_style")
+ if((species in list("Unathi", "Vulpkanin", "Tajaran"))) // Species with markings
+ var/list/valid_markings = list()
+ for(var/markingstyle in marking_styles_list)
+ var/datum/sprite_accessory/M = marking_styles_list[markingstyle]
+ if( !(species in M.species_allowed))
+ continue
+
+ valid_markings[markingstyle] = marking_styles_list[markingstyle]
+
+ var/new_marking_style = input(user, "Choose the style of your character's body markings:", "Character Preference") as null|anything in valid_markings
+ if(new_marking_style)
+ m_style = new_marking_style
+
if("body_accessory")
var/list/possible_body_accessories = list()
if(check_rights(R_ADMIN, 1, user))
@@ -1597,6 +1666,17 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
character.undershirt = undershirt
character.socks = socks
+ if(character.species.bodyflags & HAS_HEAD_ACCESSORY)
+ character.r_headacc = r_headacc
+ character.g_headacc = g_headacc
+ character.b_headacc = b_headacc
+ character.ha_style = ha_style
+ if(character.species.bodyflags & HAS_MARKINGS)
+ character.r_markings = r_markings
+ character.g_markings = g_markings
+ character.b_markings = b_markings
+ character.m_style = m_style
+
if(body_accessory)
character.body_accessory = body_accessory_by_name["[body_accessory]"]
diff --git a/code/modules/client/preferences_mysql.dm b/code/modules/client/preferences_mysql.dm
index 84d36fa9ea2..7f17b95674f 100644
--- a/code/modules/client/preferences_mysql.dm
+++ b/code/modules/client/preferences_mysql.dm
@@ -108,6 +108,16 @@
skin_red,
skin_green,
skin_blue,
+ markings_red,
+ markings_green,
+ markings_blue,
+ head_accessory_red,
+ head_accessory_green,
+ head_accessory_blue,
+ hair_style_name,
+ facial_style_name,
+ marking_style_name,
+ head_accessory_style_name,
hair_style_name,
facial_style_name,
eyes_red,
@@ -170,47 +180,55 @@
r_skin = text2num(query.item[15])
g_skin = text2num(query.item[16])
b_skin = text2num(query.item[17])
- h_style = query.item[18]
- f_style = query.item[19]
- r_eyes = text2num(query.item[20])
- g_eyes = text2num(query.item[21])
- b_eyes = text2num(query.item[22])
- underwear = query.item[23]
- undershirt = query.item[24]
- backbag = text2num(query.item[25])
- b_type = query.item[26]
+ r_markings = text2num(query.item[18])
+ g_markings = text2num(query.item[19])
+ b_markings = text2num(query.item[20])
+ r_headacc = text2num(query.item[21])
+ g_headacc = text2num(query.item[22])
+ b_headacc = text2num(query.item[23])
+ h_style = query.item[24]
+ f_style = query.item[25]
+ m_style = query.item[26]
+ ha_style = query.item[27]
+ r_eyes = text2num(query.item[28])
+ g_eyes = text2num(query.item[29])
+ b_eyes = text2num(query.item[30])
+ underwear = query.item[31]
+ undershirt = query.item[32]
+ backbag = text2num(query.item[33])
+ b_type = query.item[34]
//Jobs
- alternate_option = text2num(query.item[27])
- job_support_high = text2num(query.item[28])
- job_support_med = text2num(query.item[29])
- job_support_low = text2num(query.item[30])
- job_medsci_high = text2num(query.item[31])
- job_medsci_med = text2num(query.item[32])
- job_medsci_low = text2num(query.item[33])
- job_engsec_high = text2num(query.item[34])
- job_engsec_med = text2num(query.item[35])
- job_engsec_low = text2num(query.item[36])
- job_karma_high = text2num(query.item[37])
- job_karma_med = text2num(query.item[38])
- job_karma_low = text2num(query.item[39])
+ alternate_option = text2num(query.item[35])
+ job_support_high = text2num(query.item[36])
+ job_support_med = text2num(query.item[37])
+ job_support_low = text2num(query.item[38])
+ job_medsci_high = text2num(query.item[39])
+ job_medsci_med = text2num(query.item[40])
+ job_medsci_low = text2num(query.item[41])
+ job_engsec_high = text2num(query.item[42])
+ job_engsec_med = text2num(query.item[43])
+ job_engsec_low = text2num(query.item[44])
+ job_karma_high = text2num(query.item[45])
+ job_karma_med = text2num(query.item[46])
+ job_karma_low = text2num(query.item[47])
//Miscellaneous
- flavor_text = query.item[40]
- med_record = query.item[41]
- sec_record = query.item[42]
- gen_record = query.item[43]
- disabilities = text2num(query.item[44])
- player_alt_titles = params2list(query.item[45])
- organ_data = params2list(query.item[46])
- rlimb_data = params2list(query.item[47])
- nanotrasen_relation = query.item[48]
- speciesprefs = text2num(query.item[49])
+ flavor_text = query.item[48]
+ med_record = query.item[49]
+ sec_record = query.item[50]
+ gen_record = query.item[51]
+ disabilities = text2num(query.item[52])
+ player_alt_titles = params2list(query.item[53])
+ organ_data = params2list(query.item[54])
+ rlimb_data = params2list(query.item[55])
+ nanotrasen_relation = query.item[56]
+ speciesprefs = text2num(query.item[57])
//socks
- socks = query.item[50]
- body_accessory = query.item[51]
+ socks = query.item[58]
+ body_accessory = query.item[59]
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
@@ -233,8 +251,16 @@
r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin))
g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin))
b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin))
+ r_markings = sanitize_integer(r_markings, 0, 255, initial(r_markings))
+ g_markings = sanitize_integer(g_markings, 0, 255, initial(g_markings))
+ b_markings = sanitize_integer(b_markings, 0, 255, initial(b_markings))
+ r_headacc = sanitize_integer(r_headacc, 0, 255, initial(r_headacc))
+ g_headacc = sanitize_integer(g_headacc, 0, 255, initial(g_headacc))
+ b_headacc = sanitize_integer(b_headacc, 0, 255, initial(b_headacc))
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
+ m_style = sanitize_inlist(m_style, marking_styles_list, initial(m_style))
+ ha_style = sanitize_inlist(ha_style, head_accessory_styles_list, initial(ha_style))
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
@@ -300,8 +326,16 @@
skin_red='[r_skin]',
skin_green='[g_skin]',
skin_blue='[b_skin]',
+ markings_red='[r_markings]',
+ markings_green='[g_markings]',
+ markings_blue='[b_markings]',
+ head_accessory_red='[r_headacc]',
+ head_accessory_green='[g_headacc]',
+ head_accessory_blue='[b_headacc]',
hair_style_name='[sql_sanitize_text(h_style)]',
facial_style_name='[sql_sanitize_text(f_style)]',
+ marking_style_name='[sql_sanitize_text(m_style)]',
+ head_accessory_style_name='[sql_sanitize_text(ha_style)]',
eyes_red='[r_eyes]',
eyes_green='[g_eyes]',
eyes_blue='[b_eyes]',
@@ -351,7 +385,9 @@
hair_red, hair_green, hair_blue,
facial_red, facial_green, facial_blue,
skin_tone, skin_red, skin_green, skin_blue,
- hair_style_name, facial_style_name,
+ markings_red, markings_green, markings_blue,
+ head_accessory_red, head_accessory_green, head_accessory_blue,
+ hair_style_name, facial_style_name, marking_style_name, head_accessory_style_name,
eyes_red, eyes_green, eyes_blue,
underwear, undershirt,
backbag, b_type, alternate_option,
@@ -370,7 +406,9 @@
'[r_hair]', '[g_hair]', '[b_hair]',
'[r_facial]', '[g_facial]', '[b_facial]',
'[s_tone]', '[r_skin]', '[g_skin]', '[b_skin]',
- '[sql_sanitize_text(h_style)]', '[sql_sanitize_text(f_style)]',
+ '[r_markings]', '[g_markings]', '[b_markings]',
+ '[r_headacc]', '[g_headacc]', '[b_headacc]',
+ '[sql_sanitize_text(h_style)]', '[sql_sanitize_text(f_style)]', '[sql_sanitize_text(m_style)]', '[sql_sanitize_text(ha_style)]',
'[r_eyes]', '[g_eyes]', '[b_eyes]',
'[underwear]', '[undershirt]',
'[backbag]', '[b_type]', '[alternate_option]',
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index bc0226f4597..26612b66ed1 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -54,7 +54,7 @@
f_style = facial_hair_style
- update_hair()
+ update_fhair()
return 1
/mob/living/carbon/human/proc/reset_hair()
@@ -74,6 +74,7 @@
f_style = "Shaved"
update_hair()
+ update_fhair()
/mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue)
if(red == r_eyes && green == g_eyes && blue == b_eyes)
@@ -106,7 +107,7 @@
g_facial = green
b_facial = blue
- update_hair()
+ update_fhair()
return 1
/mob/living/carbon/human/proc/change_skin_color(var/red, var/green, var/blue)
diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm
index 2a8dfa4e458..ca94bd49baf 100644
--- a/code/modules/mob/living/carbon/human/body_accessories.dm
+++ b/code/modules/mob/living/carbon/human/body_accessories.dm
@@ -91,6 +91,8 @@ var/global/list/body_accessory_by_species = list("None" = null)
icon = 'icons/mob/body_accessory.dmi'
animated_icon = 'icons/mob/body_accessory.dmi'
blend_mode = ICON_ADD
+ icon_state = "null"
+ animated_icon_state = "null"
/datum/body_accessory/tail/try_restrictions(var/mob/living/carbon/human/H)
if(!H.wear_suit || !(H.wear_suit.flags_inv & HIDETAIL) && !istype(H.wear_suit, /obj/item/clothing/suit/space))
@@ -125,4 +127,4 @@ var/global/list/body_accessory_by_species = list("None" = null)
icon_state = "vulptail5"
animated_icon_state = "vulptail5_a"
- allowed_species = list("Vulpkanin")
\ No newline at end of file
+ allowed_species = list("Vulpkanin")
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index bac4225bd9c..2c7b2cb8bd3 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -150,6 +150,7 @@
f_style = "Shaved"
if(h_style)
h_style = "Bald"
+ update_fhair(0)
update_hair(0)
mutations.Add(SKELETON)
@@ -166,6 +167,7 @@
f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE
if(h_style)
h_style = "Bald"
+ update_fhair(0)
update_hair(0)
mutations.Add(HUSK)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 0bc919e4b0c..2e24edb8518 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -1,12 +1,25 @@
/mob/living/carbon/human
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD)
+
+ //Marking colour and style
+ var/r_markings = 0
+ var/g_markings = 0
+ var/b_markings = 0
+ var/m_style = "None"
+
//Hair colour and style
var/r_hair = 0
var/g_hair = 0
var/b_hair = 0
var/h_style = "Bald"
+ //Head accessory colour and style
+ var/r_headacc = 0
+ var/g_headacc = 0
+ var/b_headacc = 0
+ var/ha_style = "None"
+
//Facial hair colour and style
var/r_facial = 0
var/g_facial = 0
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index e728fb2db9d..4b7fa40588e 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -143,6 +143,7 @@
head = null
if(I.flags & BLOCKHAIR || I.flags & BLOCKHEADHAIR)
update_hair() //rebuild hair
+ update_fhair()
update_inv_head()
else if(I == r_ear)
r_ear = null
@@ -160,6 +161,7 @@
wear_mask = null
if(I.flags & BLOCKHAIR || I.flags & BLOCKHEADHAIR)
update_hair() //rebuild hair
+ update_fhair()
if(internal)
if(internals)
internals.icon_state = "internal0"
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index 1e85a1e2e52..056425a0966 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -40,7 +40,7 @@
flags = HAS_LIPS
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
- bodyflags = FEET_CLAWS | HAS_TAIL | HAS_SKIN_COLOR | TAIL_WAGGING
+ bodyflags = FEET_CLAWS | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING
dietflags = DIET_CARN
cold_level_1 = 280 //Default 260 - Lower is better
@@ -95,7 +95,7 @@
flags = HAS_LIPS | CAN_BE_FAT
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
- bodyflags = FEET_PADDED | HAS_TAIL | HAS_SKIN_COLOR | TAIL_WAGGING
+ bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
flesh_color = "#AFA59E"
@@ -130,7 +130,7 @@
flags = HAS_LIPS
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
- bodyflags = FEET_PADDED | HAS_TAIL | HAS_SKIN_COLOR | TAIL_WAGGING
+ bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING
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 d21aea4bde2..e1c05cc7210 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -106,30 +106,33 @@ Please contact me on #coderbus IRC. ~Carn x
//Human Overlays Indexes/////////
#define MUTANTRACE_LAYER 1
-#define MUTATIONS_LAYER 2
-#define DAMAGE_LAYER 3
-#define UNIFORM_LAYER 4
-#define ID_LAYER 5
-#define SHOES_LAYER 6
-#define GLOVES_LAYER 7
-#define EARS_LAYER 8
-#define SUIT_LAYER 9
-#define GLASSES_LAYER 10
-#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt?
-#define TAIL_LAYER 12 //bs12 specific. this hack is probably gonna come back to haunt me
-#define SUIT_STORE_LAYER 13
-#define BACK_LAYER 14
-#define HAIR_LAYER 15 //TODO: make part of head layer?
-#define FACEMASK_LAYER 16
-#define HEAD_LAYER 17
-#define COLLAR_LAYER 18
-#define HANDCUFF_LAYER 19
-#define LEGCUFF_LAYER 20
-#define L_HAND_LAYER 21
-#define R_HAND_LAYER 22
-#define TARGETED_LAYER 23 //BS12: Layer for the target overlay from weapon targeting system
-#define FIRE_LAYER 24 //If you're on fire
-#define TOTAL_LAYERS 24
+#define MARKINGS_LAYER 2
+#define MUTATIONS_LAYER 3
+#define DAMAGE_LAYER 4
+#define UNIFORM_LAYER 5
+#define ID_LAYER 6
+#define SHOES_LAYER 7
+#define GLOVES_LAYER 8
+#define EARS_LAYER 9
+#define SUIT_LAYER 10
+#define GLASSES_LAYER 11
+#define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt?
+#define TAIL_LAYER 13 //bs12 specific. this hack is probably gonna come back to haunt me
+#define SUIT_STORE_LAYER 14
+#define BACK_LAYER 15
+#define HAIR_LAYER 16 //TODO: make part of head layer?
+#define HEAD_ACCESSORY_LAYER 17
+#define FHAIR_LAYER 18
+#define FACEMASK_LAYER 19
+#define HEAD_LAYER 20
+#define COLLAR_LAYER 21
+#define HANDCUFF_LAYER 22
+#define LEGCUFF_LAYER 23
+#define L_HAND_LAYER 24
+#define R_HAND_LAYER 25
+#define TARGETED_LAYER 26 //BS12: Layer for the target overlay from weapon targeting system
+#define FIRE_LAYER 27 //If you're on fire
+#define TOTAL_LAYERS 27
@@ -350,6 +353,75 @@ var/global/list/damage_icon_parts = list()
//tail
update_tail_layer(0)
+ //head accessory
+ update_head_accessory(0)
+ //markings
+ update_markings(0)
+ //hair
+ update_hair(0)
+ update_fhair(0)
+
+
+//MARKINGS OVERLAY
+/mob/living/carbon/human/proc/update_markings(var/update_icons=1)
+ //Reset our markings
+ overlays_standing[MARKINGS_LAYER] = null
+
+ var/obj/item/organ/external/chest/chest_organ = get_organ("chest")
+ if(!chest_organ || chest_organ.is_stump() || (chest_organ.status & ORGAN_DESTROYED) )
+ if(update_icons) update_icons()
+ return
+
+ //base icons
+ var/icon/markings_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s")
+
+ if(m_style && (src.species.bodyflags & HAS_MARKINGS))
+ var/datum/sprite_accessory/marking_style = marking_styles_list[m_style]
+ if(marking_style && marking_style.species_allowed)
+ if(src.species.name in marking_style.species_allowed)
+ var/icon/markings_s = new/icon("icon" = marking_style.icon, "icon_state" = "[marking_style.icon_state]_s")
+ if(marking_style.do_colouration)
+ markings_s.Blend(rgb(r_markings, g_markings, b_markings), ICON_ADD)
+ markings_standing.Blend(markings_s, ICON_OVERLAY)
+ else
+ //warning("Invalid m_style for [species.name]: [m_style]")
+
+ overlays_standing[MARKINGS_LAYER] = image(markings_standing)
+
+ if(update_icons) update_icons()
+
+//HEAD ACCESSORY OVERLAY
+/mob/living/carbon/human/proc/update_head_accessory(var/update_icons=1)
+ //Reset our head accessory
+ overlays_standing[HEAD_ACCESSORY_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(update_icons) update_icons()
+ return
+
+ //masks and helmets can obscure our head accessory
+ if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
+ if(update_icons) update_icons()
+ return
+
+ //base icons
+ var/icon/head_accessory_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s")
+
+ if(ha_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()) && (src.species.bodyflags & HAS_HEAD_ACCESSORY)))
+ var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[ha_style]
+ if(head_accessory_style && head_accessory_style.species_allowed)
+ if(src.species.name in head_accessory_style.species_allowed)
+ var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s")
+ if(head_accessory_style.do_colouration)
+ head_accessory_s.Blend(rgb(r_headacc, g_headacc, b_headacc), ICON_ADD)
+ head_accessory_standing.Blend(head_accessory_s, ICON_OVERLAY)
+ else
+ //warning("Invalid ha_style for [species.name]: [ha_style]")
+
+ overlays_standing[HEAD_ACCESSORY_LAYER] = image(head_accessory_standing)
+
+ if(update_icons) update_icons()
//HAIR OVERLAY
@@ -367,6 +439,41 @@ var/global/list/damage_icon_parts = list()
if(update_icons) update_icons()
return
+ //base icons
+ var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
+
+ if(h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
+ var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
+ if(hair_style && hair_style.species_allowed)
+ if(src.species.name in hair_style.species_allowed)
+ var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
+ if(hair_style.do_colouration)
+ hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
+
+ hair_standing.Blend(hair_s, ICON_OVERLAY)
+ else
+ //warning("Invalid h_style for [species.name]: [h_style]")
+
+ overlays_standing[HAIR_LAYER] = image(hair_standing)
+
+ if(update_icons) update_icons()
+
+
+//FACIAL HAIR OVERLAY
+/mob/living/carbon/human/proc/update_fhair(var/update_icons=1)
+ //Reset our facial hair
+ 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(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(update_icons) update_icons()
+ return
+
//base icons
var/icon/face_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
@@ -381,19 +488,7 @@ var/global/list/damage_icon_parts = list()
else
//warning("Invalid f_style for [species.name]: [f_style]")
- if(h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
- var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
- if(hair_style && hair_style.species_allowed)
- if(src.species.name in hair_style.species_allowed)
- var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
- if(hair_style.do_colouration)
- hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
-
- face_standing.Blend(hair_s, ICON_OVERLAY)
- else
- //warning("Invalid h_style for [species.name]: [h_style]")
-
- overlays_standing[HAIR_LAYER] = image(face_standing)
+ overlays_standing[FHAIR_LAYER] = image(face_standing)
if(update_icons) update_icons()
@@ -457,6 +552,7 @@ var/global/list/damage_icon_parts = list()
skeleton = null
update_hair(0)
+ update_fhair(0)
if(update_icons) update_icons()
//Call when target overlay should be added/removed
@@ -485,6 +581,8 @@ var/global/list/damage_icon_parts = list()
update_mutations(0)
update_body(0)
update_hair(0)
+ update_head_accessory(0)
+ update_fhair(0)
update_mutantrace(0)
update_inv_w_uniform(0,0)
update_inv_wear_id(0)
@@ -1016,6 +1114,7 @@ var/global/list/damage_icon_parts = list()
//Human Overlays Indexes/////////
#undef MUTANTRACE_LAYER
+#undef MARKINGS_LAYER
#undef MUTATIONS_LAYER
#undef DAMAGE_LAYER
#undef UNIFORM_LAYER
@@ -1032,6 +1131,8 @@ var/global/list/damage_icon_parts = list()
#undef BACK_LAYER
#undef HAIR_LAYER
#undef HEAD_LAYER
+#undef HEAD_ACCESSORY_LAYER
+#undef FHAIR_LAYER
#undef COLLAR_LAYER
#undef HANDCUFF_LAYER
#undef LEGCUFF_LAYER
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index e577a2e2709..ce81f116920 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -112,7 +112,7 @@
if(self_message && M==src)
msg = self_message
M.show_message(msg, 2, deaf_message, 1)
-
+
// based on say code
var/omsg = replacetext(message, "[src] ", "")
var/list/listening_obj = new
@@ -177,6 +177,7 @@
if(ishuman(src) && W == src:head)
src:update_hair()
+ src:update_fhair()
/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1)
if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob))
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index f1b9b80e9ab..6c2dd25dcd8 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -248,36 +248,53 @@ datum/preferences
else
preview_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
+ //Body Markings
+ if(current_species && (current_species.bodyflags & HAS_MARKINGS))
+ var/datum/sprite_accessory/marking_style = marking_styles_list[m_style]
+ if(marking_style && marking_style.species_allowed)
+ var/icon/markings_s = new/icon("icon" = marking_style.icon, "icon_state" = "[marking_style.icon_state]_s")
+ markings_s.Blend(rgb(r_markings, g_markings, b_markings), ICON_ADD)
+ preview_icon.Blend(markings_s, ICON_OVERLAY)
+
+
var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = current_species ? current_species.eyes : "eyes_s")
eyes_s.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
+
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
if(hair_style)
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
eyes_s.Blend(hair_s, ICON_OVERLAY)
+ //Head Accessory
+ if(current_species && (current_species.bodyflags & HAS_HEAD_ACCESSORY))
+ var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[ha_style]
+ if(head_accessory_style && head_accessory_style.species_allowed)
+ var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s")
+ head_accessory_s.Blend(rgb(r_headacc, g_headacc, b_headacc), ICON_ADD)
+ eyes_s.Blend(head_accessory_s, ICON_OVERLAY)
+
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
- if(facial_hair_style)
+ if(facial_hair_style && facial_hair_style.species_allowed)
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
eyes_s.Blend(facial_s, ICON_OVERLAY)
-
var/icon/underwear_s = null
- if(underwear && current_species.clothing_flags & HAS_UNDERWEAR)
+ if(underwear && (current_species.clothing_flags & HAS_UNDERWEAR))
var/datum/sprite_accessory/underwear/U = underwear_list[underwear]
if(U)
underwear_s = new/icon(U.icon, "uw_[U.icon_state]_s", ICON_OVERLAY)
var/icon/undershirt_s = null
- if(undershirt && current_species.clothing_flags & HAS_UNDERSHIRT)
+ if(undershirt && (current_species.clothing_flags & HAS_UNDERSHIRT))
var/datum/sprite_accessory/undershirt/U2 = undershirt_list[undershirt]
if(U2)
undershirt_s = new/icon(U2.icon, "us_[U2.icon_state]_s", ICON_OVERLAY)
var/icon/socks_s = null
- if(socks && current_species.clothing_flags & HAS_SOCKS)
+ if(socks && (current_species.clothing_flags & HAS_SOCKS))
var/datum/sprite_accessory/socks/U3 = socks_list[socks]
if(U3)
socks_s = new/icon(U3.icon, "sk_[U3.icon_state]_s", ICON_OVERLAY)
@@ -804,8 +821,6 @@ datum/preferences
else if(backbag == 3 || backbag == 4)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY)
- if(!(current_species.bodyflags & NO_EYES))
- preview_icon.Blend(eyes_s, ICON_OVERLAY)
if(underwear_s)
preview_icon.Blend(underwear_s, ICON_OVERLAY)
if(undershirt_s)
@@ -814,6 +829,8 @@ datum/preferences
preview_icon.Blend(socks_s, ICON_OVERLAY)
if(clothes_s)
preview_icon.Blend(clothes_s, ICON_OVERLAY)
+ if(!(current_species.bodyflags & NO_EYES))
+ preview_icon.Blend(eyes_s, ICON_OVERLAY)
preview_icon_front = new(preview_icon, dir = SOUTH)
preview_icon_side = new(preview_icon, dir = WEST)
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index 1bb8c8b2a93..3043d929555 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -584,25 +584,6 @@
*/
/datum/sprite_accessory/hair
- una_spines_long
- name = "Long Unathi Spines"
- icon_state = "soghun_longspines"
- species_allowed = list("Unathi")
-
- una_spines_short
- name = "Short Unathi Spines"
- icon_state = "soghun_shortspines"
- species_allowed = list("Unathi")
-
- una_frills_long
- name = "Long Unathi Frills"
- icon_state = "soghun_longfrills"
- species_allowed = list("Unathi")
-
- una_frills_short
- name = "Short Unathi Frills"
- icon_state = "soghun_shortfrills"
- species_allowed = list("Unathi")
una_horns
name = "Unathi Horns"
@@ -645,11 +626,6 @@
species_allowed = list("Skrell")
gender = FEMALE
- taj_ears
- name = "Tajaran Ears"
- icon_state = "ears_plain"
- species_allowed = list("Tajaran")
-
taj_ears_clean
name = "Tajara Clean"
icon_state = "hair_clean"
@@ -892,6 +868,8 @@
/datum/sprite_accessory/facial_hair
+//Tajara
+
taj_sideburns
name = "Tajara Sideburns"
icon_state = "facial_sideburns"
@@ -922,6 +900,8 @@
icon_state = "facial_smallstache"
species_allowed = list("Tajaran")
+//Vox
+
vox_colonel
name = "Vox Colonel Beard"
icon_state = "vox_colonel"
@@ -957,12 +937,6 @@
species_allowed = list("Vulpkanin")
gender = NEUTER
- vulp_earfluff
- name = "Earfluff"
- icon_state = "vulp_facial_earfluff"
- species_allowed = list("Vulpkanin")
- gender = NEUTER
-
vulp_mask
name = "Mask"
icon_state = "vulp_facial_mask"
@@ -993,6 +967,51 @@
species_allowed = list("Vulpkanin")
gender = NEUTER
+//Unathi
+
+ una_spines_long
+ name = "Long Spines"
+ icon_state = "soghun_longspines"
+ species_allowed = list("Unathi")
+ gender = NEUTER
+
+ una_spines_short
+ name = "Short Spines"
+ icon_state = "soghun_shortspines"
+ species_allowed = list("Unathi")
+ gender = NEUTER
+
+ una_frills_long
+ name = "Long Frills"
+ icon_state = "soghun_longfrills"
+ species_allowed = list("Unathi")
+ gender = NEUTER
+
+ una_frills_short
+ name = "Short Frills"
+ icon_state = "soghun_shortfrills"
+ species_allowed = list("Unathi")
+ gender = NEUTER
+
+ una_frills_webbed_long
+ name = "Long Webbed Frills"
+ icon_state = "soghun_longfrills_webbed"
+ species_allowed = list("Unathi")
+ 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"
+ species_allowed = list("Unathi")
+ gender = NEUTER
+
+
//skin styles - WIP
//going to have to re-integrate this with surgery
//let the icon_state hold an icon preview for now
@@ -1518,4 +1537,132 @@
name = "Vox Fishnets"
icon_state = "vox_fishnet"
gender = NEUTER
- species_allowed = list("Vox")
\ No newline at end of file
+ species_allowed = list("Vox")
+
+/* HEAD ACCESSORY */
+
+/datum/sprite_accessory/head_accessory
+ icon = 'icons/mob/body_accessory.dmi'
+ species_allowed = list("Unathi", "Vulpkanin", "Tajaran")
+ icon_state = "accessory_none"
+
+/datum/sprite_accessory/head_accessory/none
+ name = "None"
+ species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington","Vox")
+ icon_state = "accessory_none"
+
+/datum/sprite_accessory/head_accessory/simple
+ name = "Simple"
+ species_allowed = list("Unathi")
+ icon_state = "horns_simple"
+
+/datum/sprite_accessory/head_accessory/short
+ name = "Short"
+ species_allowed = list("Unathi")
+ icon_state = "horns_short"
+
+/datum/sprite_accessory/head_accessory/curled
+ name = "Curled"
+ species_allowed = list("Unathi")
+ icon_state = "horns_curled"
+
+/datum/sprite_accessory/head_accessory/ram
+ name = "Ram"
+ species_allowed = list("Unathi")
+ icon_state = "horns_ram"
+
+/datum/sprite_accessory/head_accessory/vulp_earfluff
+ icon = 'icons/mob/human_face.dmi'
+ name = "Vulpkanin Earfluff"
+ icon_state = "vulp_facial_earfluff"
+ species_allowed = list("Vulpkanin")
+
+/datum/sprite_accessory/head_accessory/vulp_blaze
+ icon = 'icons/mob/human_face.dmi'
+ name = "Blaze"
+ icon_state = "vulp_facial_blaze"
+ species_allowed = list("Vulpkanin")
+
+/datum/sprite_accessory/head_accessory/vulp_vulpine
+ icon = 'icons/mob/human_face.dmi'
+ name = "Vulpine"
+ icon_state = "vulp_facial_vulpine"
+ species_allowed = list("Vulpkanin")
+
+/datum/sprite_accessory/head_accessory/vulp_mask
+ icon = 'icons/mob/human_face.dmi'
+ name = "Mask"
+ icon_state = "vulp_facial_mask"
+ species_allowed = list("Vulpkanin")
+
+/datum/sprite_accessory/head_accessory/vulp_patch
+ icon = 'icons/mob/human_face.dmi'
+ name = "Patch"
+ icon_state = "vulp_facial_patch"
+ species_allowed = list("Vulpkanin")
+
+/datum/sprite_accessory/head_accessory/vulp_ruff
+ icon = 'icons/mob/human_face.dmi'
+ name = "Ruff"
+ icon_state = "vulp_facial_ruff"
+ species_allowed = list("Vulpkanin")
+
+/datum/sprite_accessory/head_accessory/vulp_kita
+ icon = 'icons/mob/human_face.dmi'
+ name = "Kita"
+ icon_state = "vulp_facial_kita"
+ species_allowed = list("Vulpkanin")
+
+/datum/sprite_accessory/head_accessory/vulp_swift
+ icon = 'icons/mob/human_face.dmi'
+ name = "Swift"
+ icon_state = "vulp_facial_swift"
+ species_allowed = list("Vulpkanin")
+
+/datum/sprite_accessory/head_accessory/taj_ears
+ icon = 'icons/mob/human_face.dmi'
+ name = "Tajaran Ears"
+ icon_state = "ears_plain"
+ species_allowed = list("Tajaran")
+
+/* BODY MARKINGS */
+
+/datum/sprite_accessory/body_markings
+ icon = 'icons/mob/body_accessory.dmi'
+ species_allowed = list("Unathi", "Tajaran", "Vulpkanin")
+ icon_state = "accessory_none"
+
+/datum/sprite_accessory/body_markings/none
+ name = "None"
+ species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington","Vox")
+ icon_state = "accessory_none"
+
+/datum/sprite_accessory/body_markings/stripe
+ name = "Stripe"
+ species_allowed = list("Unathi")
+ icon_state = "markings_stripe"
+
+/datum/sprite_accessory/body_markings/tiger
+ name = "Tiger Body"
+ species_allowed = list("Unathi", "Tajaran", "Vulpkanin")
+ icon_state = "markings_tiger"
+
+/datum/sprite_accessory/body_markings/tigerhead
+ name = "Tiger Body + Head"
+ species_allowed = list("Unathi", "Tajaran", "Vulpkanin")
+ icon_state = "markings_tigerhead"
+
+/datum/sprite_accessory/body_markings/tigerheadface_taj
+ name = "Tajaran Tiger Body + Head + Face"
+ species_allowed = list("Tajaran")
+ icon_state = "markings_tigerheadface_taj"
+
+/datum/sprite_accessory/body_markings/tigerheadface_vulp
+ name = "Vulpkanin Tiger Body + Head + Face"
+ species_allowed = list("Vulpkanin")
+ icon_state = "markings_tigerheadface_vulp"
+
+/datum/sprite_accessory/body_markings/tigerheadface_una
+ name = "Unathi Tiger Body + Head + Face"
+ species_allowed = list("Unathi")
+ icon_state = "markings_tigerheadface_una"
\ No newline at end of file
diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm
index b82df310488..d464a9bdfdf 100644
--- a/code/modules/organs/subtypes/standard.dm
+++ b/code/modules/organs/subtypes/standard.dm
@@ -147,6 +147,7 @@
owner.unEquip(owner.wear_mask)
spawn(1)
owner.update_hair()
+ owner.update_fhair()
..()
/obj/item/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
diff --git a/code/modules/reagents/newchem/other.dm b/code/modules/reagents/newchem/other.dm
index 3b4bb4b2e42..46b2fe15108 100644
--- a/code/modules/reagents/newchem/other.dm
+++ b/code/modules/reagents/newchem/other.dm
@@ -204,6 +204,7 @@ datum/reagent/hair_dye/reaction_mob(var/mob/living/M, var/volume)
H.g_hair = rand(0,255)
H.b_hair = rand(0,255)
H.update_hair()
+ H.update_fhair()
..()
return
@@ -229,6 +230,7 @@ datum/reagent/hairgrownium/reaction_mob(var/mob/living/M, var/volume)
H.h_style = random_hair_style(H.gender, H.species)
H.f_style = random_facial_hair_style(H.gender, H.species)
H.update_hair()
+ H.update_fhair()
..()
return
@@ -256,6 +258,7 @@ datum/reagent/super_hairgrownium/on_mob_life(var/mob/living/M as mob)
H.h_style = "Very Long Hair"
H.f_style = "Very Long Beard"
H.update_hair()
+ H.update_fhair()
if(!H.wear_mask || H.wear_mask && !istype(H.wear_mask, /obj/item/clothing/mask/fakemoustache))
if(H.wear_mask)
H.unEquip(H.wear_mask)
diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm
index 6a9fcd3ffad..eca8911f6ad 100644
--- a/code/modules/virus2/effect.dm
+++ b/code/modules/virus2/effect.dm
@@ -593,7 +593,7 @@
if(H.species.name == "Human" && !(H.f_style == "Elvis Sideburns"))
spawn(50)
H.f_style = "Elvis Sideburns"
- H.update_hair()
+ H.update_fhair()
/obj/item/clothing/glasses/virussunglasses
@@ -805,7 +805,7 @@ var/list/compatible_mobs = list(/mob/living/carbon/human)
H << "Your chin and neck itch!."
spawn(50)
H.f_style = "Full Beard"
- H.update_hair()
+ H.update_fhair()
/datum/disease2/effect/bloodynose
name = "Intranasal Hemorrhage"
diff --git a/icons/mob/body_accessory.dmi b/icons/mob/body_accessory.dmi
index 03b9d69ab50..f79b4c262f1 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 e772ea8d048..34f7669cc85 100644
Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ