diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 454206da..66758c5d 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -1,41 +1,39 @@
-proc/random_hair_style(gender, species = "Human")
- var/h_style = "Bald"
-
- var/list/valid_hairstyles = list()
- for(var/hairstyle in hair_styles_list)
- var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
+proc/valid_sprite_accessories(gender,species,test_list)
+ var/list/valid = list()
+ for(var/style in test_list)
+ var/datum/sprite_accessory/S = test_list[style]
if( !(species in S.species_allowed))
continue
- valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
+ if (S.gender!=NEUTER)
+ if (S.gender!=gender)
+ continue
+ valid[style] = S
+ return valid
+
+proc/get_valid_hairstyles(gender, species = "Human")
+ return valid_sprite_accessories(gender,species,hair_styles_list)
+
+
+proc/get_valid_facialhairstyles(gender, species = "Human")
+ return valid_sprite_accessories(gender,species,facial_hair_styles_list)
+
+
+proc/random_hair_style(gender, species = "Human")
+ var/h_style = "Bald"
+ var/list/valid_hairstyles = get_valid_hairstyles(gender,species)
if(valid_hairstyles.len)
h_style = pick(valid_hairstyles)
-
return h_style
+
proc/random_facial_hair_style(gender, species = "Human")
var/f_style = "Shaved"
-
- var/list/valid_facialhairstyles = list()
- for(var/facialhairstyle in facial_hair_styles_list)
- var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if( !(species in S.species_allowed))
- continue
-
- valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
-
+ var/list/valid_facialhairstyles = get_valid_facialhairstyles(gender,species)
if(valid_facialhairstyles.len)
f_style = pick(valid_facialhairstyles)
-
- return f_style
+ return f_style
+
proc/random_name(gender, species = "Human")
if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 3bbd38bf..e13226e3 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -241,6 +241,9 @@ proc/checkhtml(var/t, var/whitelist = paper_tag_whitelist)
//Returns a string with the first element of the string capitalized.
/proc/capitalize(var/t as text)
return uppertext(copytext(t, 1, 2)) + copytext(t, 2)
+
+/proc/capitalized(var/t as text)
+ return capitalize(lowertext(t))
//Centers text by adding spaces to either side of the string.
/proc/dd_centertext(message, length)
diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index b15a1116..08f0a069 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -82,6 +82,9 @@
hex = text("0[]", hex)
return hex
+/proc/colour_to_html(r,g,b)
+ return "'#[num2hex(r)][num2hex(g)][num2hex(b)]'"
+
// Concatenates a list of strings into a single string. A seperator may optionally be provided.
/proc/list2text(list/ls, sep)
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index 21071711..34ae4ac5 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -14,42 +14,23 @@
if(ishuman(user))
var/mob/living/carbon/human/H = user
-
var/userloc = H.loc
-
- //see code/modules/mob/new_player/preferences.dm at approx line 545 for comments!
- //this is largely copypasted from there.
-
- //handle facial hair (if necessary)
- if(H.gender == MALE)
- var/list/species_facial_hair = list()
- if(H.species)
- for(var/i in facial_hair_styles_list)
- var/datum/sprite_accessory/facial_hair/tmp_facial = facial_hair_styles_list[i]
- if(H.species.name in tmp_facial.species_allowed)
- species_facial_hair += i
- else
- species_facial_hair = facial_hair_styles_list
-
- var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in species_facial_hair
+
+ var/list/hair_styles = H.valid_hairstyles_for_this_mob()
+ var/list/facial_styles = H.valid_facialhairstyles_for_this_mob()
+
+ if (facial_styles.len > 1) //handle facial hair (if necessary)
+ var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in facial_styles
if(userloc != H.loc) return //no tele-grooming
if(new_style)
H.f_style = new_style
//handle normal hair
- var/list/species_hair = list()
- if(H.species)
- for(var/i in hair_styles_list)
- var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i]
- if(H.species.name in tmp_hair.species_allowed)
- species_hair += i
- else
- species_hair = hair_styles_list
-
- var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in species_hair
- if(userloc != H.loc) return //no tele-grooming
- if(new_style)
- H.h_style = new_style
+ if (hair_styles.len)
+ var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in hair_styles
+ if(userloc != H.loc) return //no tele-grooming
+ if(new_style)
+ H.h_style = new_style
H.update_hair()
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index dd6963e3..5f12b74f 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -78,6 +78,8 @@ datum/preferences
var/species = "Human" //Species datum to use.
var/language = "None" //Secondary language
var/list/gear //Custom/fluff item loadout.
+ var/covering_type = null //synth covering type
+ var/machine_brain_type = "Posibrain" //synth brain type
//Some faction information.
var/home_system = "Unset" //System of birth.
@@ -315,43 +317,21 @@ datum/preferences
dat += "Skin Tone: [-s_tone + 35]/220
"
//dat += "Skin pattern: Adjust
"
dat += "Needs Glasses: [disabilities == 0 ? "No" : "Yes"]
"
+ if (species=="Machine") // brain and covering type for shells
+ dat += "Brain Type: [machine_brain_type]
"
+ dat += "Exterior Coating: [isnull(covering_type) ? "None" : covering_type]
"
dat += "Limbs: Adjust
"
dat += "Internal Organs: Adjust
"
//display limbs below
var/ind = 0
+ var/list/organ_names = get_limb_name_to_descriptive_name()
+ var/mechanical_organ_string = (species!="Machine" ? "Mechanical" : "Custom")
for(var/name in organ_data)
//world << "[ind] \ [organ_data.len]"
var/status = organ_data[name]
- var/organ_name = null
- switch(name)
- if("l_arm")
- organ_name = "left arm"
- if("r_arm")
- organ_name = "right arm"
- if("l_leg")
- organ_name = "left leg"
- if("r_leg")
- organ_name = "right leg"
- if("l_foot")
- organ_name = "left foot"
- if("r_foot")
- organ_name = "right foot"
- if("l_hand")
- organ_name = "left hand"
- if("r_hand")
- organ_name = "right hand"
- if("heart")
- organ_name = "heart"
- if("eyes")
- organ_name = "eyes"
-
- if(status == "cyborg")
- ++ind
- if(ind > 1)
- dat += ", "
- dat += "\tMechanical [organ_name] prothesis"
- else if(status == "amputated")
+ var/organ_name = organ_names[name]
+ if(status == "amputated")
++ind
if(ind > 1)
dat += ", "
@@ -374,10 +354,20 @@ datum/preferences
dat += "\tRetinal overlayed [organ_name]"
else
dat += "\tMechanically assisted [organ_name]"
+ var/list/status_as_list=status
+ if (istype(status_as_list)) // we got a robot here
+ ++ind
+ if(ind > 1)
+ dat += ", "
+
+ var/color_string=colour_to_html(status_as_list[2],status_as_list[3],status_as_list[4])
+ dat += "\t[mechanical_organ_string] [organ_name] covered in [lowertext(status_as_list[1])]"
+
+
if(!ind)
dat += "\[...\]
"
else
- dat += "
"
+ dat += ".
"
if(gender == MALE)
dat += "Underwear: [underwear_m[underwear]]
"
@@ -1112,6 +1102,7 @@ datum/preferences
if(new_age)
age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
if("species")
+ config.usealienwhitelist=0 // REMOVE ME
var/list/new_species = list("Human")
var/prev_species = species
@@ -1131,42 +1122,9 @@ datum/preferences
if(prev_species != species)
//grab one of the valid hair styles for the newly chosen species
- var/list/valid_hairstyles = list()
- for(var/hairstyle in hair_styles_list)
- var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if( !(species in S.species_allowed))
- continue
- valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
-
- if(valid_hairstyles.len)
- h_style = pick(valid_hairstyles)
- else
- //this shouldn't happen
- h_style = hair_styles_list["Bald"]
-
- //grab one of the valid facial hair styles for the newly chosen species
- var/list/valid_facialhairstyles = list()
- for(var/facialhairstyle in facial_hair_styles_list)
- var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if( !(species in S.species_allowed))
- continue
-
- valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
-
- if(valid_facialhairstyles.len)
- f_style = pick(valid_facialhairstyles)
- else
- //this shouldn't happen
- f_style = facial_hair_styles_list["Shaved"]
-
+ h_style = random_hair_style(gender,species)
+ f_style = random_facial_hair_style(gender,species)
+
//reset hair colour and skin colour
r_hair = 0//hex2num(copytext(new_hair, 2, 4))
g_hair = 0//hex2num(copytext(new_hair, 4, 6))
@@ -1208,24 +1166,15 @@ datum/preferences
b_type = new_b_type
if("hair")
- if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell")
- var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as color|null
- if(new_hair)
- r_hair = hex2num(copytext(new_hair, 2, 4))
- g_hair = hex2num(copytext(new_hair, 4, 6))
- b_hair = hex2num(copytext(new_hair, 6, 8))
- else if (species == "Machine")
- alert("Please select the Body Color instead.")
+ var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as color|null
+ if(new_hair)
+ r_hair = hex2num(copytext(new_hair, 2, 4))
+ g_hair = hex2num(copytext(new_hair, 4, 6))
+ b_hair = hex2num(copytext(new_hair, 6, 8))
if("h_style")
- var/list/valid_hairstyles = list()
- for(var/hairstyle in hair_styles_list)
- var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
- if( !(species in S.species_allowed))
- continue
-
- valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
-
+ world << "Hair species [get_hair_species()]"
+ var/list/valid_hairstyles = get_valid_hairstyles(gender,get_hair_species())
var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles
if(new_h_style)
h_style = new_h_style
@@ -1238,18 +1187,7 @@ datum/preferences
b_facial = hex2num(copytext(new_facial, 6, 8))
if("f_style")
- var/list/valid_facialhairstyles = list()
- for(var/facialhairstyle in facial_hair_styles_list)
- var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
- if(gender == MALE && S.gender == FEMALE)
- continue
- if(gender == FEMALE && S.gender == MALE)
- continue
- if( !(species in S.species_allowed))
- continue
-
- valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
-
+ var/list/valid_facialhairstyles = get_valid_facialhairstyles(gender,get_hair_species())
var/new_f_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in valid_facialhairstyles
if(new_f_style)
f_style = new_f_style
@@ -1296,10 +1234,6 @@ datum/preferences
r_skin = hex2num(copytext(new_skin, 2, 4))
g_skin = hex2num(copytext(new_skin, 4, 6))
b_skin = hex2num(copytext(new_skin, 6, 8))
- if(species == "Machine")
- r_hair = r_skin
- g_hair = g_skin
- b_hair = b_skin
if("ooccolor")
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null
@@ -1324,58 +1258,20 @@ datum/preferences
return
else
user << browse(null, "window=disabil")
-
+
+ if("set_machine_brain") // shell customization junk
+ var/new_brain = input(user, "Choose your brain.", "Character Preference") as null|anything in list("MMI", "Posibrain") // not differentiating brain species at the moment
+ if(new_brain)
+ machine_brain_type=new_brain
+
+ if("set_machine_covering")
+ var/new_coating = input(user, "Choose your exterior coating.", "Character Preference") as null|anything in get_limb_covering_names()
+ if(new_coating)
+ covering_type=(new_coating!="None" ? new_coating : null)
+
if("limbs")
- var/limb_name = input(user, "Which limb do you want to change?") as null|anything in list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand")
- if(!limb_name) return
-
- var/limb = null
- var/second_limb = null // if you try to change the arm, the hand should also change
- var/third_limb = null // if you try to unchange the hand, the arm should also change
- switch(limb_name)
- if("Left Leg")
- limb = "l_leg"
- second_limb = "l_foot"
- if("Right Leg")
- limb = "r_leg"
- second_limb = "r_foot"
- if("Left Arm")
- limb = "l_arm"
- second_limb = "l_hand"
- if("Right Arm")
- limb = "r_arm"
- second_limb = "r_hand"
- if("Left Foot")
- limb = "l_foot"
- third_limb = "l_leg"
- if("Right Foot")
- limb = "r_foot"
- third_limb = "r_leg"
- if("Left Hand")
- limb = "l_hand"
- third_limb = "l_arm"
- if("Right Hand")
- limb = "r_hand"
- third_limb = "r_arm"
-
- var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in list("Normal","Amputated","Prothesis")
- if(!new_state) return
-
- switch(new_state)
- if("Normal")
- organ_data[limb] = null
- if(third_limb)
- organ_data[third_limb] = null
- if("Amputated")
- organ_data[limb] = "amputated"
- if(second_limb)
- organ_data[second_limb] = "amputated"
- if("Prothesis")
- organ_data[limb] = "cyborg"
- if(second_limb)
- organ_data[second_limb] = "cyborg"
- if(third_limb && organ_data[third_limb] == "amputated")
- organ_data[third_limb] = null
+ customize_limbs(user,species!="Machine")
+
if("organs")
var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes")
if(!organ_name) return
@@ -1597,26 +1493,42 @@ datum/preferences
character.skills = skills
character.used_skillpoints = used_skillpoints
+
+ var/list/covering_name_to_type = get_limb_covering_list()
+ // provide default covering for shells
+ if (species=="Machine") // provide default covering for shells
+ for (var/datum/organ/external/organ in character.organs)
+ if (organ) // gotta make sure we're getting an actual organ here
+ if (covering_type)
+ var/covering_path = covering_name_to_type[covering_type]
+ world << "Skin [r_skin],[g_skin],b_skin]"
+ organ.covering = new covering_path(organ,r_skin,g_skin,b_skin)
+ organ.covering.limb_datum=organ
+
+
// Destroy/cyborgize organs
-
for(var/name in organ_data)
var/datum/organ/external/O = character.organs_by_name[name]
var/datum/organ/internal/I = character.internal_organs_by_name[name]
var/status = organ_data[name]
-
if(status == "amputated")
O.amputated = 1
O.status |= ORGAN_DESTROYED
O.destspawn = 1
- if(status == "cyborg")
- O.status |= ORGAN_ROBOT
if(status == "assisted")
I.mechassist()
- else if(status == "mechanical")
+ if(status == "mechanical")
I.mechanize()
-
- else continue
+ var/list/status_as_list=status
+ if (istype(status_as_list)) // we got a robot here
+ world << "We setting this junk"
+ O.status |= ORGAN_ROBOT
+ O.covering = null // wipe any old covering we might have
+ if (status_as_list[1]!="None")
+ var/covering_path = covering_name_to_type[status_as_list[1]]
+ O.covering = new covering_path(O,status_as_list[2],status_as_list[3],status_as_list[4])
+ O.covering.limb_datum=O
if(underwear > underwear_m.len || underwear < 1)
underwear = 0 //I'm sure this is 100% unnecessary, but I'm paranoid... sue me. //HAH NOW NO MORE MAGIC CLONING UNDIES
@@ -1659,3 +1571,104 @@ datum/preferences
/datum/preferences/proc/close_load_dialog(mob/user)
user << browse(null, "window=saves")
+
+
+/datum/preferences/proc/get_hair_species()
+ // this is incredibly snowflakey but I don't see an alternative
+ if (!species=="Machine")
+ return species
+ var/head_coat=covering_type // we get the base coating
+ if (organ_data["Head"]) // if we're customizing the head we should get their coating
+ head_coat=organ_data["Head"][0]
+ if (!head_coat)
+ return
+ var/list/refs=get_limb_covering_references()
+ for(var/skin_type in refs)
+ var/datum/synthetic_limb_cover/temp=refs[skin_type]
+ if (temp.icon_key_type==head_coat)
+ return temp.hair_species
+
+
+/datum/preferences/proc/custom_robot_limb(mob/user,)
+ var/covering_name = input(user, "What kind of covering do you want?") as null|anything in get_limb_covering_names()
+ if (!covering_name)
+ return
+ if (covering_name=="None") // don't want no colour
+ return list(covering_name,128,128,128)
+ var/new_colour = input(user, "Pick the colour for your limb:", "Character Preference") as color|null
+ if(!new_colour)
+ return
+ return list(covering_name,hex2num(copytext(new_colour, 2, 4)),hex2num(copytext(new_colour, 4, 6)),hex2num(copytext(new_colour, 6, 8)))
+
+
+var/list/limb_name_to_descriptive_names
+/datum/preferences/proc/get_limb_name_to_descriptive_name()
+ if (isnull(limb_name_to_descriptive_names))
+ limb_name_to_descriptive_names=list()
+ for(var/organ_type in typesof(/datum/organ/external)-/datum/organ/external)
+ var/datum/organ/external/temp = new organ_type()
+ limb_name_to_descriptive_names[temp.name]=temp.display_name
+ del(temp)
+ return limb_name_to_descriptive_names
+
+
+var/list/limb_connection_data
+/datum/preferences/proc/get_limb_connection_data()
+ if (isnull(limb_connection_data))
+ limb_connection_data = list()
+ limb_connection_data["Left Leg"]=list("l_leg","l_foot",null)
+ limb_connection_data["Right Leg"]=list("r_leg","r_foot",null)
+ limb_connection_data["Left Arm"]=list("l_arm","l_hand",null)
+ limb_connection_data["Right Arm"]=list("r_arm","r_hand",null)
+ limb_connection_data["Left Foot"]=list("l_foot",null,"l_leg")
+ limb_connection_data["Right Foot"]=list("r_foot",null,"r_leg")
+ limb_connection_data["Left Hand"]=list("l_hand",null,"l_arm")
+ limb_connection_data["Right Hand"]=list("r_hand",null,"r_arm")
+ limb_connection_data["Chest"]=list("chest",null,null)
+ limb_connection_data["Groin"]=list("groin",null,null)
+ limb_connection_data["Head"]=list("head",null,null)
+ return limb_connection_data
+
+
+/datum/preferences/proc/pick_organ_to_customize(mob/user,var/is_organic_species)
+ var/list/valid_targets = list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand")
+ if (!is_organic_species)
+ valid_targets.Add(list("Head","Chest","Groin"))
+ var/limb_name = input(user, "Which limb do you want to change?") as null|anything in valid_targets
+ if(!limb_name) // you have picked nothing
+ return
+ var/list/limb_info=get_limb_connection_data()
+ return limb_info[limb_name]
+
+
+/datum/preferences/proc/customize_limbs(mob/user,var/is_organic_species)
+ var/list/limb_info = pick_organ_to_customize(user,is_organic_species)
+ world << "We done picked! [limb_info]"
+ if (!limb_info)
+ return
+ var/limb=limb_info[1]
+ var/limb_child=limb_info[2]
+ var/limb_parent=limb_info[3]
+ world << "LIMB STUFF [limb] [limb_child] [limb_parent]"
+ var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in (is_organic_species ? list("Normal","Amputated","Prosthesis") : list("Normal","Custom"))
+ if(!new_state)
+ return // cancel
+ switch(new_state)
+ if("Normal")
+ organ_data[limb] = null
+ if(limb_parent)
+ organ_data[limb_parent] = null
+ if("Amputated")
+ organ_data[limb] = "amputated"
+ if(limb_child)
+ organ_data[limb_child] = "amputated"
+ if("Prosthesis")
+ var/list/custom = custom_robot_limb(user)
+ organ_data[limb] = custom
+ world << "[organ_data[limb][1]] [organ_data[limb][2]] [organ_data[limb][3]][organ_data[limb][4]]"
+ if(limb_child)
+ organ_data[limb_child] = custom
+ if(limb_parent && organ_data[limb_parent] == "amputated")
+ organ_data[limb_parent] = null
+ if("Custom")
+ organ_data[limb] = custom_robot_limb(user) // robots have no dependencies
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index decf0bf3..a78c9d65 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1659,3 +1659,82 @@
if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY)
return 1
return 0
+
+/mob/living/carbon/human/proc/hair_species_name()
+ var/datum/organ/external/head/head_organ = get_organ("head")
+ if (head_organ.covering)
+ return head_organ.covering.hair_species
+ return species.name
+
+
+/mob/living/carbon/human/proc/valid_hairstyles_for_this_mob()
+ return get_valid_hairstyles(gender, hair_species_name())
+
+
+/mob/living/carbon/human/proc/valid_facialhairstyles_for_this_mob()
+ return get_valid_facialhairstyles(gender, hair_species_name())
+
+
+/mob/living/carbon/human/proc/should_we_show_hair()
+ var/datum/organ/external/head/head_organ = get_organ("head")
+ if(!head_organ || (head_organ.status & ORGAN_DESTROYED))
+ return
+ if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
+ return
+ return TRUE
+
+/mob/living/carbon/human/proc/validate_hair()
+ var/list/hair=valid_hairstyles_for_this_mob()
+ if (!(h_style in hair))
+ h_style=null
+ var/list/face=valid_facialhairstyles_for_this_mob()
+ if (!(f_style in face))
+ f_style=null
+
+
+/mob/living/carbon/human/proc/hair_icon()
+ if (h_style)
+ var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
+ var/icon/hair = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
+ if(hair_style.do_colouration)
+ hair.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
+ return hair
+
+
+/mob/living/carbon/human/proc/facial_hair_icon()
+ if (f_style)
+ var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
+ var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
+ if(facial_hair_style.do_colouration)
+ facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
+ return facial_s
+
+
+/mob/living/carbon/human/proc/get_eye_icon_state()
+ var/datum/organ/external/head/head_organ = get_organ("head")
+ if (head_organ.covering)
+ return head_organ.covering.eyes_state
+ return species.eyes
+
+
+/mob/living/carbon/human/proc/eye_icon()
+ var/icon/result_icon = new/icon('icons/mob/human_face.dmi', get_eye_icon_state())
+ result_icon.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
+ return result_icon
+
+
+/mob/living/carbon/human/proc/tail_icon_state()
+ var/datum/organ/external/groin/groin_organ = get_organ("groin")
+ if (groin_organ.covering)
+ return groin_organ.covering.tail
+ if (species.tail)
+ return species.tail
+
+
+/mob/living/carbon/human/proc/tail_icon()
+ var/tail_name = tail_icon_state()
+ if (tail_name)
+ if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space))
+ var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail_name]_s")
+ tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
+ return tail_s
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_species.dm b/code/modules/mob/living/carbon/human/human_species.dm
index c313c601..ea550240 100644
--- a/code/modules/mob/living/carbon/human/human_species.dm
+++ b/code/modules/mob/living/carbon/human/human_species.dm
@@ -30,5 +30,5 @@
..(new_loc, "Diona")
/mob/living/carbon/human/machine/New(var/new_loc)
- h_style = "blue IPC screen"
+ h_style = "Bald"
..(new_loc, "Machine")
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 8c52146b..38cd24aa 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -234,6 +234,49 @@ proc/get_damage_icon_part(damage_state, body_part)
overlays_standing[DAMAGE_LAYER] = standing_image
if(update_icons) update_icons()
+
+
+/mob/living/carbon/human/proc/get_skin_tone_key()
+ if (species.flags & HAS_SKIN_COLOR)
+ return "[r_skin],[g_skin],[b_skin]"
+ if(species.flags & HAS_SKIN_TONE)
+ return "[s_tone]"
+ return ""
+
+
+/mob/living/carbon/human/proc/get_icon_key(var/list/mutations=list())
+ if (!mutations)
+ mutations=get_visible_mutations()
+ var/icon_key = "[species.race_key][(gender == FEMALE ? "f" : "m")][get_skin_tone_key()]"
+ for(var/datum/organ/external/part in organs) // get the part icon keys
+ icon_key = "[icon_key][part.get_icon_key()]"
+ return "[icon_key][mutations["husk"]][mutations["fat"]][mutations["hulk"]][mutations["skeleton"]]"
+
+
+/mob/living/carbon/human/proc/get_visible_mutations()
+ return list("husk"=(HUSK in src.mutations),
+ "hulk"=(HULK in src.mutations),
+ "skeleton"=(SKELETON in src.mutations),
+ "fat"=(FAT in src.mutations))
+
+
+/mob/living/carbon/human/proc/skin_colour_info(var/list/mutations=list())
+ if (!mutations)
+ mutations=get_visible_mutations()
+ var/icon_blend=ICON_ADD
+ var/colour=rgb(127,127,127)
+ var/good=FALSE
+ if (species.flags & HAS_SKIN_COLOR)
+ colour=rgb(r_skin,g_skin,b_skin)
+ good=TRUE
+ if(!mutations["husk"] && !mutations["hulk"]) // if we have regular skin
+ if(species.flags & HAS_SKIN_TONE)
+ icon_blend=(s_tone >= 0 ? ICON_ADD : ICON_SUBTRACT)
+ var/res=(s_tone >= 0 ? s_tone : -s_tone)
+ colour=rgb(res,res,res)
+ good=TRUE
+ return list("rgb"=colour,"mode"=icon_blend,"blend"=good)
+
//BASE MOB SPRITE
/mob/living/carbon/human/proc/update_body(var/update_icons=1)
@@ -242,13 +285,8 @@ proc/get_damage_icon_part(damage_state, body_part)
var/hulk_color_mod = rgb(48,224,40)
var/necrosis_color_mod = rgb(10,50,0)
- var/husk = (HUSK in src.mutations)
- var/fat = (FAT in src.mutations)
- var/hulk = (HULK in src.mutations)
- var/skeleton = (SKELETON in src.mutations)
-
+ var/list/mutations = get_visible_mutations()
var/g = (gender == FEMALE ? "f" : "m")
- var/has_head = 0
//CACHING: Generate an index key from visible bodyparts.
//0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic.
@@ -259,22 +297,9 @@ proc/get_damage_icon_part(damage_state, body_part)
stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank")
- var/icon_key = "[species.race_key][g][s_tone]"
- for(var/datum/organ/external/part in organs)
- if(istype(part,/datum/organ/external/head) && !(part.status & ORGAN_DESTROYED))
- has_head = 1
-
- if(part.status & ORGAN_DESTROYED)
- icon_key = "[icon_key]0"
- else if(part.status & ORGAN_ROBOT)
- icon_key = "[icon_key]2"
- else if(part.status & ORGAN_DEAD)
- icon_key = "[icon_key]3"
- else
- icon_key = "[icon_key]1"
-
- icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0][s_tone]"
+ // GENERATE THE ICON KEY
+ var/icon_key = get_icon_key(mutations)
var/icon/base_icon
if(human_icon_cache[icon_key])
@@ -287,14 +312,18 @@ proc/get_damage_icon_part(damage_state, body_part)
//BEGIN CACHED ICON GENERATION.
- // Why don't we just make skeletons/shadows/golems a species? ~Z
- var/race_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase)
- var/deform_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase)
+ // Why don't we just make mutations["skeleton"]s/shadows/golems a species? ~Z
+ var/race_icon = (mutations["skeleton"] ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase)
+ var/deform_icon = (mutations["skeleton"] ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase)
+ var/list/skin_info = skin_colour_info(mutations) // get the skin tone info
+
//Robotic limbs are handled in get_icon() so all we worry about are missing or dead limbs.
//No icon stored, so we need to start with a basic one.
var/datum/organ/external/chest = get_organ("chest")
- base_icon = chest.get_icon(race_icon,deform_icon,g)
+ base_icon = chest.get_icon(race_icon,deform_icon,skin_info)
+
+
if(chest.status & ORGAN_DEAD)
base_icon.ColorTone(necrosis_color_mod)
@@ -307,10 +336,7 @@ proc/get_damage_icon_part(damage_state, body_part)
if(part.status & ORGAN_DESTROYED)
continue
- if (istype(part, /datum/organ/external/groin) || istype(part, /datum/organ/external/head))
- temp = part.get_icon(race_icon,deform_icon,g)
- else
- temp = part.get_icon(race_icon,deform_icon)
+ temp = part.get_icon(race_icon,deform_icon,skin_info) // synthetics are handled here
if(part.status & ORGAN_DEAD)
temp.ColorTone(necrosis_color_mod)
@@ -345,48 +371,33 @@ proc/get_damage_icon_part(damage_state, body_part)
base_icon.Blend(temp, ICON_OVERLAY)
- if(!skeleton)
- if(husk)
+ if(!mutations["skeleton"])
+ if(mutations["husk"])
base_icon.ColorTone(husk_color_mod)
- else if(hulk)
+ else if(mutations["hulk"])
var/list/tone = ReadRGB(hulk_color_mod)
base_icon.MapColors(rgb(tone[1],0,0),rgb(0,tone[2],0),rgb(0,0,tone[3]))
- //Handle husk overlay.
- if(husk)
+ //Handle mutations["husk"] overlay.
+ if(mutations["husk"])
var/icon/mask = new(base_icon)
var/icon/husk_over = new(race_icon,"overlay_husk")
mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0)
husk_over.Blend(mask, ICON_ADD)
base_icon.Blend(husk_over, ICON_OVERLAY)
-
- //Skin tone.
- if(!husk && !hulk)
- if(species.flags & HAS_SKIN_TONE)
- if(s_tone >= 0)
- base_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
- else
- base_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
-
human_icon_cache[icon_key] = base_icon
//log_debug("Generated new cached mob icon ([icon_key] \icon[human_icon_cache[icon_key]]) for [src]. [human_icon_cache.len] cached mob icons.")
//END CACHED ICON GENERATION.
-
stand_icon.Blend(base_icon,ICON_OVERLAY)
- //Skin colour. Not in cache because highly variable (and relatively benign).
- if (species.flags & HAS_SKIN_COLOR)
- stand_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
-
- if(has_head)
+ var/datum/organ/external/head = get_organ("head") // check if we have a head
+ if(head ? (head.status & ORGAN_DESTROYED ? 0 : 1) : 0) // we need a head and that head needs to not be destroyed
//Eyes
- if(!skeleton)
- var/icon/eyes = new/icon('icons/mob/human_face.dmi', species.eyes)
- eyes.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
- stand_icon.Blend(eyes, ICON_OVERLAY)
+ if(!mutations["skeleton"])
+ stand_icon.Blend(eye_icon(), ICON_OVERLAY)
//Mouth (lipstick!)
if(lip_style && (species && species.flags & HAS_LIPS)) //skeletons are allowed to wear lipstick no matter what you think, agouri.
@@ -394,7 +405,7 @@ proc/get_damage_icon_part(damage_state, body_part)
//Underwear
if(underwear >0 && underwear < 12 && species.flags & HAS_UNDERWEAR)
- if(!fat && !skeleton)
+ if(!mutations["fat"] && !mutations["skeleton"])
stand_icon.Blend(new /icon('icons/mob/human.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY)
if(undershirt>0 && undershirt <= undershirt_t.len && species.flags & HAS_UNDERWEAR)
@@ -407,47 +418,27 @@ proc/get_damage_icon_part(damage_state, body_part)
update_tail_showing(0)
+/mob/living/carbon/human/proc/create_hair_icon()
+ if(!should_we_show_hair()) // if we're missing our head or we're wearing a mask, no hair
+ return
+ validate_hair() // make sure our hair is valid
+ var/icon/face_standing = new /icon('icons/mob/human_face.dmi',"bald_s") //base icons
+ var/icon/facial_s = facial_hair_icon()
+ if (facial_s)
+ face_standing.Blend(facial_s, ICON_OVERLAY)
+ var/icon/hair_s = hair_icon()
+ if (hair_s)
+ face_standing.Blend(hair_s, ICON_OVERLAY)
+ overlays_standing[HAIR_LAYER] = image(face_standing)
//HAIR OVERLAY
/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
- //Reset our hair
- overlays_standing[HAIR_LAYER] = null
-
- var/datum/organ/external/head/head_organ = get_organ("head")
- if( !head_organ || (head_organ.status & ORGAN_DESTROYED) )
- if(update_icons) update_icons()
- return
-
- //masks and helmets can obscure our hair.
- 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")
-
- if(f_style)
- var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
- if(facial_hair_style && facial_hair_style.species_allowed && src.species.name in facial_hair_style.species_allowed)
- var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
- if(facial_hair_style.do_colouration)
- facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
-
- face_standing.Blend(facial_s, ICON_OVERLAY)
-
- if(h_style && !(head && (head.flags & BLOCKHEADHAIR)))
- var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
- if(hair_style && 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)
-
- overlays_standing[HAIR_LAYER] = image(face_standing)
-
- if(update_icons) update_icons()
+ overlays_standing[HAIR_LAYER] = null //Reset our hair
+ create_hair_icon() // do the hair blending
+ if(update_icons)
+ update_icons()
+
/mob/living/carbon/human/update_mutations(var/update_icons=1)
var/fat
@@ -988,16 +979,12 @@ proc/get_damage_icon_part(damage_state, body_part)
overlays_standing[L_HAND_LAYER] = null
if(update_icons) update_icons()
+
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
overlays_standing[TAIL_LAYER] = null
-
- if(species.tail)
- if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space))
- var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
- tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
-
- overlays_standing[TAIL_LAYER] = image(tail_s)
-
+ var/icon/tail_s = tail_icon()
+ if (tail_s)
+ overlays_standing[TAIL_LAYER] = image(tail_s)
if(update_icons)
update_icons()
diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm
index 8837307a..b5043fd2 100644
--- a/code/modules/mob/living/carbon/species.dm
+++ b/code/modules/mob/living/carbon/species.dm
@@ -105,6 +105,11 @@
//H.jitteriness = 0
H.update_hair()
return
+
+
+/datum/species/proc/get_eye_icon()
+ return eyes
+
/datum/species/human
name = "Human"
@@ -328,6 +333,9 @@
blood_color = "#1F181F"
flesh_color = "#575757"
+
+ var/brain_type = 'posibrain' // default is robots
+
//Species unarmed attacks
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index fe20acd3..3375be3a 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -43,6 +43,10 @@
// how often wounds should be updated, a higher number means less often
var/wound_update_accuracy = 1
+
+ var/datum/synthetic_limb_cover/covering = null // paint or synth skin
+
+ var/gendered = FALSE
/datum/organ/external/New(var/datum/organ/external/P)
@@ -804,14 +808,52 @@ Note that amputating the affected organ does in fact remove the infection from t
return 1
return 0
-/datum/organ/external/get_icon(var/icon/race_icon, var/icon/deform_icon,gender="")
- if (status & ORGAN_ROBOT && !(owner.species && owner.species.flags & IS_SYNTHETIC))
- return new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
+
+/datum/organ/external/proc/get_icon_key()
+ if (status & ORGAN_DESTROYED)
+ return "L" // l for lost
+ if (status & ORGAN_DEAD)
+ return "D" // d for dead
+ if (status & ORGAN_ROBOT)
+ return get_synthetic_icon_key()
+ return "G" // regular old limb
- if (status & ORGAN_MUTATED)
- return new /icon(deform_icon, "[icon_name][gender ? "_[gender]" : ""]")
- return new /icon(race_icon, "[icon_name][gender ? "_[gender]" : ""]")
+/datum/organ/external/proc/valid_covering()
+ if (status & ORGAN_ROBOT)
+ if (covering)
+ return (covering.coverage) // is our covering working?
+ return FALSE // if we have no covering at all
+ return TRUE // squishies always have skin
+
+
+/datum/organ/external/proc/get_synthetic_icon_key()
+ if (!covering) // no covering at all, this should not happen
+ return "R" // regular old robot
+ return covering.get_icon_key()
+
+
+/datum/organ/external/proc/get_synthetic_icon()
+ if (!covering) // no covering at all, this should not happen
+ return new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][get_gender_string()]")
+ return covering.get_icon()
+
+
+/datum/organ/external/proc/get_gender_string()
+ if (!gendered) // most organs aren't gender specific
+ return ""
+ if (owner) // if we're a gender specific organ with an owner
+ return (owner.gender == FEMALE ? "_f" : "_m")
+ return "_f"
+
+
+/datum/organ/external/get_icon(var/icon/race_icon, var/icon/deform_icon, var/list/skin_info)
+ if (status & ORGAN_ROBOT)
+ return get_synthetic_icon()
+ var/icon/result = new /icon((status & ORGAN_MUTATED) ? deform_icon : race_icon, "[icon_name][get_gender_string()]")
+ if (skin_info["blend"])
+ result.Blend(skin_info["rgb"],skin_info["mode"])
+ return result
/datum/organ/external/proc/is_usable()
@@ -867,6 +909,7 @@ Note that amputating the affected organ does in fact remove the infection from t
body_part = UPPER_TORSO
vital = 1
encased = "ribcage"
+ gendered = TRUE
/datum/organ/external/groin
name = "groin"
@@ -876,6 +919,7 @@ Note that amputating the affected organ does in fact remove the infection from t
min_broken_damage = 30
body_part = LOWER_TORSO
vital = 1
+ gendered = TRUE
/datum/organ/external/l_arm
name = "l_arm"
@@ -971,16 +1015,7 @@ Note that amputating the affected organ does in fact remove the infection from t
var/disfigured = 0
vital = 1
encased = "skull"
-
-/datum/organ/external/head/get_icon(var/icon/race_icon, var/icon/deform_icon)
- if (!owner)
- return ..()
- var/g = "m"
- if(owner.gender == FEMALE) g = "f"
- if (status & ORGAN_MUTATED)
- . = new /icon(deform_icon, "[icon_name]_[g]")
- else
- . = new /icon(race_icon, "[icon_name]_[g]")
+ gendered = TRUE
/datum/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
..(brute, burn, sharp, edge, used_weapon, forbidden_limbs)
@@ -1012,6 +1047,7 @@ obj/item/weapon/organ
icon = 'icons/mob/human_races/r_human.dmi'
var/op_stage = 0
var/list/organs_internal = list()
+
obj/item/weapon/organ/New(loc, mob/living/carbon/human/H)
..(loc)
@@ -1039,24 +1075,13 @@ obj/item/weapon/organ/New(loc, mob/living/carbon/human/H)
base = icon(H.species.icobase)
else
base = icon('icons/mob/human_races/r_human.dmi')
-
- if(base)
- //Changing limb's skin tone to match owner
- if(!H.species || H.species.flags & HAS_SKIN_TONE)
- if (H.s_tone >= 0)
- base.Blend(rgb(H.s_tone, H.s_tone, H.s_tone), ICON_ADD)
- else
- base.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT)
-
- if(base)
- //Changing limb's skin color to match owner
- if(!H.species || H.species.flags & HAS_SKIN_COLOR)
- base.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD)
-
+ if(base) // handle skin colours
+ var/list/skin_info = H.skin_colour_info() // get the skin tone info
+ base.Blend(skin_info["rgb"],skin_info["mode"])
icon = base
set_dir(SOUTH)
src.transform = turn(src.transform, rand(70,130))
-
+
/****************************************************
EXTERNAL ORGAN ITEMS DEFINES
diff --git a/code/modules/organs/synth_skin.dm b/code/modules/organs/synth_skin.dm
new file mode 100644
index 00000000..ece7ca76
--- /dev/null
+++ b/code/modules/organs/synth_skin.dm
@@ -0,0 +1,127 @@
+/*
+
+We need to mix blending into limb object code, this will slow shit down a lot.
+
+*/
+
+#define SYNTHETIC_COVERING_WORKING 1
+#define SYNTHETIC_COVERING_DAMAGED 0
+
+datum/synthetic_limb_cover
+ var/coverage //
+ var/colour_r = 128 // the colour of the limb
+ var/colour_g = 128// the colour of the limb
+ var/colour_b = 128// the colour of the limb
+ var/datum/organ/external/limb_datum // the limb in question
+ var/obj/item/robot_parts/limb_item // also the limb in question (if dismembered)
+ var/main_icon = 'icons/mob/human_races/robotic.dmi'
+ var/damage_icon = 'icons/mob/human_races/robotic.dmi'
+ var/icon_key_type="BAD"
+ var/hair_species=null
+ var/eyes_state = "blank_eyes"
+ var/tail = null
+
+
+datum/synthetic_limb_cover/New( var/datum/organ/external/datum_target=null,var/input_colour_r=null,var/input_colour_g=null,var/input_colour_b=null)
+ world << "Making cover : [src]"
+ limb_datum=datum_target
+ coverage=SYNTHETIC_COVERING_WORKING // start working
+ if(input_colour_r)
+ colour_r=input_colour_r
+ if(input_colour_g)
+ colour_g=input_colour_g
+ if(input_colour_b)
+ colour_b=input_colour_b
+
+ world << "COLOUR is [colour_r]-[colour_g]-[colour_b]"
+
+
+datum/synthetic_limb_cover/proc/get_icon() // default mechanical limbs return robo versions
+ var/icon/temp = new /icon((coverage ? main_icon : damage_icon), "[limb_datum.icon_name][limb_datum.get_gender_string()]") // only add a gender if it's necessary
+ var/icon/result = icon(temp)
+ result.GrayScale()
+ result.Blend(rgb(colour_r,colour_g,colour_b), ICON_ADD)
+ return result
+
+
+datum/synthetic_limb_cover/proc/repair()
+ coverage = SYNTHETIC_COVERING_WORKING
+
+
+datum/synthetic_limb_cover/proc/damage()
+ coverage = SYNTHETIC_COVERING_DAMAGED
+
+
+datum/synthetic_limb_cover/proc/recolour(var/paint_colour_r, var/paint_colour_g, var/paint_colour_b, var/update=FALSE)
+ colour_r=paint_colour_r
+ colour_g=paint_colour_g
+ colour_b=paint_colour_b
+ if (update)
+ if (limb_datum)
+ if (limb_datum.owner)
+ limb_datum.owner.update_body()
+
+
+datum/synthetic_limb_cover/proc/get_icon_key() // this is going to wreck the icon cache but to do custom colour per limb this is necessary
+ return "SYNTH:[icon_key_type]:[colour_r][colour_g][colour_b]"
+
+
+datum/synthetic_limb_cover/paint
+ main_icon = 'icons/mob/human_races/r_machine.dmi'
+ icon_key_type = "Paint"
+ hair_species = "Machine"
+
+
+datum/synthetic_limb_cover/skin
+ main_icon = 'icons/mob/human_races/r_human_grey.dmi'
+ icon_key_type = "Skin"
+ hair_species = "Human"
+ eyes_state="eyes_s"
+
+
+datum/synthetic_limb_cover/fur
+ main_icon = 'icons/mob/human_races/r_tajaran.dmi'
+ icon_key_type = "Fur"
+ hair_species = "Tajaran"
+ eyes_state="eyes_s"
+ tail = "tajtail"
+
+
+datum/synthetic_limb_cover/scales
+ main_icon = 'icons/mob/human_races/r_lizard.dmi'
+ icon_key_type = "Scales"
+ hair_species = "Unathi"
+ eyes_state="eyes_s"
+ tail = "sogtail"
+
+
+var/list/limb_covering_references
+/proc/get_limb_covering_references()
+ if (isnull(limb_covering_references))
+ limb_covering_references = list()
+ for(var/skin_type in typesof(/datum/synthetic_limb_cover)-/datum/synthetic_limb_cover)
+ var/datum/synthetic_limb_cover/temp_cover = new skin_type()
+ limb_covering_references[skin_type]=temp_cover
+ return limb_covering_references
+
+
+var/list/limb_covering_names
+/proc/get_limb_covering_names()
+ if (isnull(limb_covering_names))
+ limb_covering_names=list("None")
+ var/list/refs=get_limb_covering_references()
+ for(var/skin_type in refs)
+ var/datum/synthetic_limb_cover/temp=refs[skin_type]
+ limb_covering_names.Add(temp.icon_key_type)
+ return limb_covering_names
+
+
+var/list/limb_covering_list
+/proc/get_limb_covering_list()
+ if(isnull(limb_covering_list))
+ limb_covering_list=list("None"=null)
+ var/list/refs=get_limb_covering_references()
+ for(var/skin_type in refs)
+ var/datum/synthetic_limb_cover/temp=refs[skin_type]
+ limb_covering_list[temp.icon_key_type]=skin_type
+ return limb_covering_list
\ No newline at end of file
diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi
index 0f28d76a..1f65c43f 100644
Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ
diff --git a/icons/mob/human_races/r_human_grey.dmi b/icons/mob/human_races/r_human_grey.dmi
new file mode 100644
index 00000000..0404ad8f
Binary files /dev/null and b/icons/mob/human_races/r_human_grey.dmi differ