diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index de485d12056..893ee78e65e 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -141,7 +141,7 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
temp = new /icon(icobase, "groin_[g]")
preview_icon.Blend(temp, ICON_OVERLAY)
var/head = "head"
- if(head_organ.alt_head)
+ if(head_organ.alt_head && head_organ.species.bodyflags & HAS_ALT_HEADS)
var/datum/sprite_accessory/alt_heads/alternate_head = alt_heads_list[head_organ.alt_head]
if(alternate_head.icon_state)
head = alternate_head.icon_state
diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm
index a6be779f037..df66ba13a40 100644
--- a/code/game/dna/genes/vg_powers.dm
+++ b/code/game/dna/genes/vg_powers.dm
@@ -46,9 +46,6 @@
var/new_eyes = input("Please select eye color.", "Character Generation", rgb(M.r_eyes,M.g_eyes,M.b_eyes)) as null|color
if(new_eyes)
- M.r_eyes = hex2num(copytext(new_eyes, 2, 4))
- M.g_eyes = hex2num(copytext(new_eyes, 4, 6))
- M.b_eyes = hex2num(copytext(new_eyes, 6, 8))
M.change_eye_color(M.r_eyes, M.g_eyes, M.b_eyes)
//Alt heads.
@@ -64,85 +61,33 @@
// if new style selected (not cancel)
if(new_style)
- head_organ.h_style = new_style
+ M.change_hair(new_style)
var/new_hair = input("Please select hair color.", "Character Generation", rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair)) as null|color
if(new_hair)
- head_organ.r_hair = hex2num(copytext(new_hair, 2, 4))
- head_organ.g_hair = hex2num(copytext(new_hair, 4, 6))
- head_organ.b_hair = hex2num(copytext(new_hair, 6, 8))
+ M.change_hair_color(hex2num(copytext(new_hair, 2, 4)), hex2num(copytext(new_hair, 4, 6)), hex2num(copytext(new_hair, 6, 8)))
// facial hair
var/list/valid_facial_hairstyles = M.generate_valid_facial_hairstyles()
new_style = input("Please select facial style", "Character Generation", head_organ.f_style) as null|anything in valid_facial_hairstyles
if(new_style)
- head_organ.f_style = new_style
+ M.change_facial_hair(new_style)
var/new_facial = input("Please select facial hair color.", "Character Generation", rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial)) as null|color
if(new_facial)
- head_organ.r_facial = hex2num(copytext(new_facial, 2, 4))
- head_organ.g_facial = hex2num(copytext(new_facial, 4, 6))
- head_organ.b_facial = hex2num(copytext(new_facial, 6, 8))
+ M.change_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()
var/new_head_accessory = input("Please select head accessory style", "Character Generation", head_organ.ha_style) as null|anything in valid_head_accessories
if(new_head_accessory)
- head_organ.ha_style = new_head_accessory
+ M.change_head_accessory(new_head_accessory)
var/new_head_accessory_colour = input("Please select head accessory colour.", "Character Generation", rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc)) as null|color
if(new_head_accessory_colour)
- head_organ.r_headacc = hex2num(copytext(new_head_accessory_colour, 2, 4))
- head_organ.g_headacc = hex2num(copytext(new_head_accessory_colour, 4, 6))
- head_organ.b_headacc = hex2num(copytext(new_head_accessory_colour, 6, 8))
-
- //Head markings.
- if(M.species.bodyflags & HAS_HEAD_MARKINGS)
- var/list/marking_styles = params2list(M.m_styles)
- var/list/valid_head_markings = M.generate_valid_markings("head")
- var/new_marking = input("Please select head marking style", "Character Generation", marking_styles["head"]) as null|anything in valid_head_markings
- if(new_marking)
- marking_styles["head"] = new_marking
- M.m_styles = list2params(marking_styles)
-
- var/list/marking_colours = params2list(M.m_colours)
- marking_colours["head"] = sanitize_hexcolor(marking_colours["head"])
- var/new_marking_colour = input("Please select head marking colour.", "Character Generation", rgb(hex2num(copytext(marking_colours["head"], 2, 4)), hex2num(copytext(marking_colours["head"], 4, 6)), hex2num(copytext(marking_colours["head"], 6, 8)))) as null|color
- if(new_marking_colour)
- marking_colours["head"] = new_marking_colour
- M.m_colours = list2params(marking_colours)
- //Body markings.
- if(M.species.bodyflags & HAS_BODY_MARKINGS)
- var/list/marking_styles = params2list(M.m_styles)
- var/list/valid_body_markings = M.generate_valid_markings("body")
- var/new_marking = input("Please select body marking style", "Character Generation", marking_styles["body"]) as null|anything in valid_body_markings
- if(new_marking)
- marking_styles["body"] = new_marking
- M.m_styles = list2params(marking_styles)
-
- var/list/marking_colours = params2list(M.m_colours)
- marking_colours["body"] = sanitize_hexcolor(marking_colours["body"])
- var/new_marking_colour = input("Please select body marking colour.", "Character Generation", rgb(hex2num(copytext(marking_colours["body"], 2, 4)), hex2num(copytext(marking_colours["body"], 4, 6)), hex2num(copytext(marking_colours["body"], 6, 8)))) as null|color
- if(new_marking_colour)
- marking_colours["body"] = new_marking_colour
- M.m_colours = list2params(marking_colours)
- //Tail markings.
- if(M.species.bodyflags & HAS_TAIL_MARKINGS)
- var/list/marking_styles = params2list(M.m_styles)
- var/list/valid_tail_markings = M.generate_valid_markings("tail")
- var/new_marking = input("Please select tail marking style", "Character Generation", marking_styles["tail"]) as null|anything in valid_tail_markings
- if(new_marking)
- marking_styles["tail"] = new_marking
- M.m_styles = list2params(marking_styles)
-
- var/list/marking_colours = params2list(M.m_colours)
- marking_colours["tail"] = sanitize_hexcolor(marking_colours["tail"])
- var/new_marking_colour = input("Please select tail marking colour.", "Character Generation", rgb(hex2num(copytext(marking_colours["tail"], 2, 4)), hex2num(copytext(marking_colours["tail"], 4, 6)), hex2num(copytext(marking_colours["tail"], 6, 8)))) as null|color
- if(new_marking_colour)
- marking_colours["tail"] = new_marking_colour
- M.m_colours = list2params(marking_colours)
+ M.change_head_accessory_color(hex2num(copytext(new_head_accessory_colour, 2, 4)), hex2num(copytext(new_head_accessory_colour, 4, 6)), hex2num(copytext(new_head_accessory_colour, 6, 8)))
//Body accessory.
if(M.species.tail && M.species.bodyflags & HAS_TAIL)
@@ -150,14 +95,56 @@
if(valid_body_accessories.len > 1) //By default valid_body_accessories will always have at the very least a 'none' entry populating the list, even if the user's species is not present in any of the list items.
var/new_body_accessory = input("Please select body accessory style", "Character Generation", M.body_accessory) as null|anything in valid_body_accessories
if(new_body_accessory)
- M.body_accessory = body_accessory_by_name[new_body_accessory]
+ M.change_body_accessory(new_body_accessory)
+
+ //Head markings.
+ if(M.species.bodyflags & HAS_HEAD_MARKINGS)
+ var/list/marking_styles = params2list(M.m_styles)
+ var/list/valid_head_markings = M.generate_valid_markings("head")
+ var/new_marking = input("Please select head marking style", "Character Generation", marking_styles["head"]) as null|anything in valid_head_markings
+ if(new_marking)
+ M.change_markings(new_marking, "head")
+
+ var/list/marking_colours = params2list(M.m_colours)
+ marking_colours["head"] = sanitize_hexcolor(marking_colours["head"])
+ var/new_marking_colour = input("Please select head marking colour.", "Character Generation", rgb(hex2num(copytext(marking_colours["head"], 2, 4)), hex2num(copytext(marking_colours["head"], 4, 6)), hex2num(copytext(marking_colours["head"], 6, 8)))) as null|color
+ if(new_marking_colour)
+ M.change_marking_color(new_marking_colour, "head")
+ //Body markings.
+ if(M.species.bodyflags & HAS_BODY_MARKINGS)
+ var/list/marking_styles = params2list(M.m_styles)
+ var/list/valid_body_markings = M.generate_valid_markings("body")
+ var/new_marking = input("Please select body marking style", "Character Generation", marking_styles["body"]) as null|anything in valid_body_markings
+ if(new_marking)
+ M.change_markings(new_marking, "body")
+
+ var/list/marking_colours = params2list(M.m_colours)
+ marking_colours["body"] = sanitize_hexcolor(marking_colours["body"])
+ var/new_marking_colour = input("Please select body marking colour.", "Character Generation", rgb(hex2num(copytext(marking_colours["body"], 2, 4)), hex2num(copytext(marking_colours["body"], 4, 6)), hex2num(copytext(marking_colours["body"], 6, 8)))) as null|color
+ if(new_marking_colour)
+ M.change_marking_color(new_marking_colour, "body")
+ //Tail markings.
+ if(M.species.bodyflags & HAS_TAIL_MARKINGS)
+ var/list/marking_styles = params2list(M.m_styles)
+ var/list/valid_tail_markings = M.generate_valid_markings("tail")
+ var/new_marking = input("Please select tail marking style", "Character Generation", marking_styles["tail"]) as null|anything in valid_tail_markings
+ if(new_marking)
+ M.change_markings(new_marking, "tail")
+
+ var/list/marking_colours = params2list(M.m_colours)
+ marking_colours["tail"] = sanitize_hexcolor(marking_colours["tail"])
+ var/new_marking_colour = input("Please select tail marking colour.", "Character Generation", rgb(hex2num(copytext(marking_colours["tail"], 2, 4)), hex2num(copytext(marking_colours["tail"], 4, 6)), hex2num(copytext(marking_colours["tail"], 6, 8)))) as null|color
+ if(new_marking_colour)
+ M.change_marking_color(new_marking_colour, "tail")
//Skin tone.
if(M.species.bodyflags & HAS_SKIN_TONE)
var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", M.s_tone) as null|text
if(!new_tone)
new_tone = 35
- M.s_tone = 35 - max(min(round(text2num(new_tone)), 220), 1)
+ else
+ new_tone = 35 - max(min(round(text2num(new_tone)), 220), 1)
+ M.change_skin_tone(new_tone)
if(M.species.bodyflags & HAS_ICON_SKIN_TONE)
var/prompt = "Please select skin tone: 1-[M.species.icon_skin_tones.len] ("
@@ -170,18 +157,16 @@
var/new_tone = input(prompt, "Character Generation", M.s_tone) as null|text
if(!new_tone)
new_tone = 0
- M.s_tone = max(min(round(text2num(new_tone)), M.species.icon_skin_tones.len), 1)
+ else
+ new_tone = max(min(round(text2num(new_tone)), M.species.icon_skin_tones.len), 1)
+ M.change_skin_tone(new_tone)
//Skin colour.
if(M.species.bodyflags & HAS_SKIN_COLOR)
var/new_body_colour = input("Please select body colour.", "Character Generation", rgb(M.r_skin, M.g_skin, M.b_skin)) as null|color
if(new_body_colour)
- M.r_skin = hex2num(copytext(new_body_colour, 2, 4))
- M.g_skin = hex2num(copytext(new_body_colour, 4, 6))
- M.b_skin = hex2num(copytext(new_body_colour, 6, 8))
+ M.change_skin_color(hex2num(copytext(new_body_colour, 2, 4)), hex2num(copytext(new_body_colour, 4, 6)), hex2num(copytext(new_body_colour, 6, 8)))
- M.force_update_limbs()
- M.regenerate_icons()
M.update_dna()
M.visible_message("[src] morphs and changes [M.get_visible_gender() == MALE ? "his" : M.get_visible_gender() == FEMALE ? "her" : "their"] appearance!", "You change your appearance!", "Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!")
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index 147aa5da6d9..aa47e5252ab 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -131,7 +131,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
var/r_eyes = 0 //Eye color
var/g_eyes = 0 //Eye color
var/b_eyes = 0 //Eye color
- var/alt_head = null //Alt head style.
+ var/alt_head = "None" //Alt head style.
var/species = "Human"
var/language = "None" //Secondary language
@@ -1268,6 +1268,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
m_styles = "head=None;\
body=None;\
tail=None" // No Unathi markings on Tajara
+
alt_head = null //No alt heads on species that don't have them.
body_accessory = null //no vulptail on humans damnit
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index 5d6fb9260b7..134dbaf4b42 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -77,6 +77,15 @@
if(marking.name != "None" && (!H.heads_allowed || !(head_organ.alt_head in H.heads_allowed)))
return
+ if(location == "tail" && marking.name != "None")
+ var/datum/sprite_accessory/body_markings/tail/tail_marking = marking_styles_list[marking_style]
+ if(!body_accessory)
+ if(tail_marking.tails_allowed)
+ return
+ else
+ if(!tail_marking.tails_allowed || !(body_accessory.name in tail_marking.tails_allowed))
+ return
+
marking_styles[location] = marking_style
m_styles = list2params(marking_styles)
@@ -107,7 +116,7 @@
/mob/living/carbon/human/proc/change_alt_head(var/alternate_head)
var/obj/item/organ/external/head/H = get_organ("head")
- if(H.alt_head == alternate_head || (H.status & ORGAN_ROBOT) || !(species.bodyflags & HAS_ALT_HEADS) || !(alternate_head in alt_heads_list))
+ if(H.alt_head == alternate_head || (H.status & ORGAN_ROBOT) || (!(species.bodyflags & HAS_ALT_HEADS) && alternate_head != "None") || !(alternate_head in alt_heads_list))
return
H.alt_head = alternate_head
@@ -262,7 +271,6 @@
b_skin = blue
force_update_limbs()
- update_body()
return 1
/mob/living/carbon/human/proc/change_skin_tone(var/tone)
@@ -386,7 +394,7 @@
if(S.tails_allowed)
continue
else
- if(!S.tails_allowed || !(body_accessory in S.tails_allowed))
+ if(!S.tails_allowed || !(body_accessory.name in S.tails_allowed))
continue
if(location == "head")
var/datum/sprite_accessory/body_markings/head/M = marking_styles_list[S.name]
diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm
index d54a892e8e2..7b0309dc1ac 100644
--- a/code/modules/mob/living/carbon/human/species/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station.dm
@@ -117,7 +117,7 @@
flags = HAS_LIPS | CAN_BE_FAT
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
- bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_BODY_MARKINGS | HAS_HEAD_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING | HAS_FUR
+ bodyflags = FEET_PADDED | HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING | HAS_FUR
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
flesh_color = "#AFA59E"
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index 7c6426ed93d..e5fa2656436 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -222,7 +222,7 @@
preview_icon = new /icon(icobase, "torso_[g][fat]")
preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY)
var/head = "head"
- if(alt_head)
+ if(alt_head && current_species.bodyflags & HAS_ALT_HEADS)
var/datum/sprite_accessory/alt_heads/H = alt_heads_list[alt_head]
if(H.icon_state)
head = H.icon_state
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index f2f31463e5d..484b2e525be 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -67,7 +67,7 @@
name = "Bald"
icon_state = "bald"
gender = MALE
- species_allowed = list("Human", "Unathi", "Vox", "Diona", "Kidan", "Grey", "Plasmaman", "Skeleton")
+ species_allowed = list("Human", "Unathi", "Vox", "Diona", "Kidan", "Grey", "Plasmaman", "Skeleton", "Vulpkanin", "Tajaran")
short
name = "Short Hair" // try to capatilize the names please~
@@ -773,6 +773,31 @@
icon_state = "hair_messy"
species_allowed = list("Tajaran")
+ taj_hair_curls
+ name = "Tajara Curly"
+ icon_state = "hair_curly"
+ species_allowed = list("Tajaran")
+
+ taj_hair_wife
+ name = "Tajaran Ladies' Retro"
+ icon_state = "hair_ladies_retro"
+ species_allowed = list("Tajaran")
+
+ taj_hair_victory
+ name = "Tajara Victory Curls"
+ icon_state = "hair_victory"
+ species_allowed = list("Tajaran")
+
+ taj_hair_bob
+ name = "Tajara Bob"
+ icon_state = "hair_tbob"
+ species_allowed = list("Tajaran")
+
+ taj_hair_fingercurl
+ name = "Tajara Finger Curls"
+ icon_state = "hair_fingerwave"
+ species_allowed = list("Tajaran")
+
//Vulpkanin
vulp_hair_none
@@ -1800,6 +1825,26 @@
species_allowed = list("Unathi")
icon_state = "horns_ram"
+/datum/sprite_accessory/head_accessory/outears_taj
+ name = "Tajaran Outer Ears"
+ species_allowed = list("Tajaran")
+ icon_state = "markings_face_outears_taj"
+
+/datum/sprite_accessory/head_accessory/inears_taj
+ name = "Tajaran Inner Ears"
+ species_allowed = list("Tajaran")
+ icon_state = "markings_face_inears_taj"
+
+/datum/sprite_accessory/head_accessory/muzzle_taj
+ name = "Tajaran Muzzle"
+ species_allowed = list("Tajaran")
+ icon_state = "markings_face_muzzle_taj"
+
+/datum/sprite_accessory/head_accessory/muzzle_and_inears_taj
+ name = "Tajaran Muzzle and Inner Ears"
+ species_allowed = list("Tajaran")
+ icon_state = "markings_face_muzzle_and_inears_taj"
+
/datum/sprite_accessory/head_accessory/vulp_earfluff
icon = 'icons/mob/human_face.dmi'
name = "Vulpkanin Earfluff"
@@ -1995,6 +2040,11 @@
icon_state = "markings_face_snout_lower_una"
heads_allowed = list("Unathi Sharp Snout")
+/datum/sprite_accessory/body_markings/head/nose_taj
+ name = "Tajaran Nose"
+ species_allowed = list("Tajaran")
+ icon_state = "markings_face_nose_taj"
+
/datum/sprite_accessory/body_markings/head/nose_default_vulp
name = "Vulpkanin Nose"
species_allowed = list("Vulpkanin")
diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm
index f992c1dc92b..61baafa1b62 100644
--- a/code/modules/surgery/organs/subtypes/standard.dm
+++ b/code/modules/surgery/organs/subtypes/standard.dm
@@ -140,7 +140,7 @@
gendered_icon = 1
encased = "skull"
var/can_intake_reagents = 1
- var/alt_head = null
+ var/alt_head = "None"
//Hair colour and style
var/r_hair = 0
@@ -200,5 +200,8 @@
var/datum/sprite_accessory/alt_heads/alternate_head = alt_heads_list[alt_head]
if(alternate_head.icon_state)
icon_name = alternate_head.icon_state
- else
+ else //If alternate_head.icon_state doesn't exist, that means alternate_head is "None", so default icon_name back to "head".
icon_name = initial(icon_name)
+ else //If alt_head is null, set it to "None" and default icon_name for sanity.
+ alt_head = initial(alt_head)
+ icon_name = initial(icon_name)
diff --git a/icons/mob/body_accessory.dmi b/icons/mob/body_accessory.dmi
index ac2a5ed38c7..d3e11579d8e 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 c3c1746c1a1..5d4144f35fd 100644
Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ