From 3b6f7996c4376a198832bdb8501a842b2db98bf2 Mon Sep 17 00:00:00 2001 From: Matt Atlas Date: Sat, 9 Nov 2019 10:23:42 +0100 Subject: [PATCH] Human Sprites 2: The Desimpsonifying (#7057) --- code/__defines/species_languages.dm | 1 + code/_helpers/global_lists.dm | 1 + code/modules/admin/admin_verbs.dm | 4 +- .../preference_setup/general/01_basic.dm | 1 + .../preference_setup/general/03_body.dm | 39 +- code/modules/client/preferences.dm | 6 +- .../abstract/new_player/preferences_setup.dm | 362 +++++++++--------- .../mob/living/carbon/human/appearance.dm | 5 +- .../living/carbon/human/species/species.dm | 1 + .../human/species/station/human/human.dm | 6 +- .../species/station/ipc/ipc_subspecies.dm | 5 +- code/modules/nano/modules/human_appearance.dm | 18 +- code/modules/organs/organ_icon.dm | 10 +- .../mattatlaspoze-newhumansprites.yml | 41 ++ icons/mob/human_races/human/human_preview.dmi | Bin 366 -> 419 bytes icons/mob/human_races/human/r_def_human.dmi | Bin 8613 -> 6543 bytes icons/mob/human_races/human/r_human.dmi | Bin 8155 -> 6347 bytes nano/templates/appearance_changer.tmpl | 5 +- 18 files changed, 300 insertions(+), 205 deletions(-) create mode 100644 html/changelogs/mattatlaspoze-newhumansprites.yml diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index dac3613318e..3f5b16ef917 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -30,6 +30,7 @@ #define HAS_HAIR_COLOR 0x20 // Hair colour selectable in chargen. (RGB) #define HAS_SOCKS 0x40 // If this species can wear socks #define HAS_FBP 0x80 // If for whatever ungodly reason we decide to ever have non-Shell FBPs. +#define HAS_SKIN_PRESET 0x100 // Skin color presets selectable in character generation. // Tau-Ceti basic, language common to all crew. #define LANGUAGE_TCB "Ceti Basic" diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 8c54e26643c..d9e87a13c64 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -56,6 +56,7 @@ var/global/list/facial_hair_styles_female_list = list() var/global/list/skin_styles_female_list = list() //unused var/global/list/body_marking_styles_list = list() var/global/list/chargen_disabilities_list = list() + //Underwear var/global/list/underwear_m = list("White" = "m1", "Grey" = "m2", "Green" = "m3", "Blue" = "m4", "Black" = "m5", "Mankini" = "m6", "Boxers" = "boxers", "Green and blue boxers" = "boxers_green_and_blue","Loveheart boxers" = "boxers_loveheart","None") //Curse whoever made male/female underwear diffrent colours var/global/list/underwear_f = list("Red" = "f1", "White" = "f2", "Yellow" = "f3", "Blue" = "f4", "Black" = "f5", "Thong" = "f6", "Black Sports" = "f7","White Sports" = "f8","None") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index b94f3fd61d6..e96248e7034 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -936,10 +936,10 @@ var/list/admin_verbs_cciaa = list( M.g_skin = hex2num(copytext(new_skin, 4, 6)) M.b_skin = hex2num(copytext(new_skin, 6, 8)) - var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as text + var/new_tone = input("Please select skin tone level: 30-220. Higher is darker.", "Character Generation") as text if (new_tone) - M.s_tone = max(min(round(text2num(new_tone)), 220), 1) + M.s_tone = max(min(round(text2num(new_tone)), 220), 30) M.s_tone = -M.s_tone + 35 // hair diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 1a0d8f8eef3..b45f8d6c663 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -143,6 +143,7 @@ var/datum/category_item/player_setup_item/general/equipment/equipment_item = category.items[4] equipment_item.sanitize_character() // sanitize equipment + pref.update_preview_icon() return TOPIC_REFRESH else if(href_list["age"]) diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index d4b57eb8d94..8fcfcf368c3 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -160,7 +160,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.r_facial = sanitize_integer(pref.r_facial, 0, 255, initial(pref.r_facial)) pref.g_facial = sanitize_integer(pref.g_facial, 0, 255, initial(pref.g_facial)) pref.b_facial = sanitize_integer(pref.b_facial, 0, 255, initial(pref.b_facial)) - pref.s_tone = sanitize_integer(pref.s_tone, -185, 34, initial(pref.s_tone)) + pref.s_tone = sanitize_integer(pref.s_tone, -185, 5, initial(pref.s_tone)) pref.r_skin = sanitize_integer(pref.r_skin, 0, 255, initial(pref.r_skin)) pref.g_skin = sanitize_integer(pref.g_skin, 0, 255, initial(pref.g_skin)) pref.b_skin = sanitize_integer(pref.b_skin, 0, 255, initial(pref.b_skin)) @@ -294,9 +294,15 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O out += "
Eyes
" out += "Change Color [HTML_RECT(rgb(pref.r_eyes, pref.g_eyes, pref.b_eyes))]
" - if(has_flag(mob_species, HAS_SKIN_COLOR)) - out += "
Body Color
" - out += "Change Color [HTML_RECT(rgb(pref.r_skin, pref.g_skin, pref.b_skin))]
" + if(has_flag(mob_species, HAS_SKIN_COLOR) || has_flag(mob_species, HAS_SKIN_PRESET)) + if(has_flag(mob_species, HAS_SKIN_PRESET)) + out += "
Body Color Presets
" + out += "Choose Preset
" + else + out += "
Body Color
" + out += "Change Color [HTML_RECT(rgb(pref.r_skin, pref.g_skin, pref.b_skin))]
" + + out += "
Body Markings +
" for(var/M in pref.body_markings) @@ -444,19 +450,28 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O else if(href_list["skin_tone"]) if(!has_flag(mob_species, HAS_SKIN_TONE)) return TOPIC_NOACTION - var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference", (-pref.s_tone) + 35) as num|null + var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 30 - 220 Dark)", "Character Preference", (-pref.s_tone) + 35) as num|null if(new_s_tone && has_flag(mob_species, HAS_SKIN_TONE) && CanUseTopic(user)) - pref.s_tone = 35 - max(min( round(new_s_tone), 220),1) + pref.s_tone = 35 - max(min( round(new_s_tone), 220),30) return TOPIC_REFRESH else if(href_list["skin_color"]) - if(!has_flag(mob_species, HAS_SKIN_COLOR)) + if(!has_flag(mob_species, HAS_SKIN_COLOR) && !has_flag(mob_species, HAS_SKIN_PRESET)) return TOPIC_NOACTION - var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", rgb(pref.r_skin, pref.g_skin, pref.b_skin)) as color|null - if(new_skin && has_flag(mob_species, HAS_SKIN_COLOR) && CanUseTopic(user)) - pref.r_skin = GetRedPart(new_skin) - pref.g_skin = GetGreenPart(new_skin) - pref.b_skin = GetBluePart(new_skin) + if(has_flag(mob_species, HAS_SKIN_COLOR) && !has_flag(mob_species, HAS_SKIN_PRESET)) + var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", rgb(pref.r_skin, pref.g_skin, pref.b_skin)) as color|null + if(new_skin && has_flag(mob_species, HAS_SKIN_COLOR) && CanUseTopic(user)) + pref.r_skin = GetRedPart(new_skin) + pref.g_skin = GetGreenPart(new_skin) + pref.b_skin = GetBluePart(new_skin) + return TOPIC_REFRESH + + else if(has_flag(mob_species, HAS_SKIN_PRESET)) + var/new_preset = input(user, "Choose your character's body color preset:", "Character Preference", rgb(pref.r_skin, pref.g_skin, pref.b_skin)) as null|anything in mob_species.character_color_presets + new_preset = mob_species.character_color_presets[new_preset] + pref.r_skin = GetRedPart(new_preset) + pref.g_skin = GetGreenPart(new_preset) + pref.b_skin = GetBluePart(new_preset) return TOPIC_REFRESH else if(href_list["facial_style"]) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 7e3f4408d8d..fc58328af30 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -55,9 +55,9 @@ datum/preferences var/b_facial = 0 //Face hair color var/s_tone = 0 //Skin tone var/skin_colour = "#000000" //Skin colour hex value, for SQL loading - var/r_skin = 0 //Skin color - var/g_skin = 0 //Skin color - var/b_skin = 0 //Skin color + var/r_skin = 37 //Skin color + var/g_skin = 3 //Skin color + var/b_skin = 2 //Skin color var/eyes_colour = "#000000" //Eye colour hex value, for SQL loading var/r_eyes = 0 //Eye color var/g_eyes = 0 //Eye color diff --git a/code/modules/mob/abstract/new_player/preferences_setup.dm b/code/modules/mob/abstract/new_player/preferences_setup.dm index 18f0e7a327e..a9281d46e80 100644 --- a/code/modules/mob/abstract/new_player/preferences_setup.dm +++ b/code/modules/mob/abstract/new_player/preferences_setup.dm @@ -1,197 +1,204 @@ -datum/preferences +/datum/preferences //The mob should have a gender you want before running this proc. Will run fine without H - proc/randomize_appearance_for(var/mob/living/carbon/human/H,var/random_gender=TRUE) - if(random_gender) - gender = pick(MALE, FEMALE) - else - gender = H.gender - var/datum/species/current_species = all_species[species] +/datum/preferences/proc/randomize_appearance_for(var/mob/living/carbon/human/H,var/random_gender=TRUE) + if(random_gender) + gender = pick(MALE, FEMALE) + else + gender = H.gender + var/datum/species/current_species = all_species[species] - if(current_species) - if(current_species.appearance_flags & HAS_SKIN_TONE) - s_tone = random_skin_tone() - if(current_species.appearance_flags & HAS_EYE_COLOR) - randomize_eyes_color() - if(current_species.appearance_flags & HAS_SKIN_COLOR) - randomize_skin_color() - if(current_species.appearance_flags & HAS_UNDERWEAR) - if(gender == FEMALE) - underwear = underwear_f[pick(underwear_f)] - else - underwear = underwear_m[pick(underwear_m)] - undershirt = undershirt_t[pick(undershirt_t)] - if(current_species.appearance_flags & HAS_SOCKS) - if(gender == FEMALE) - socks = socks_f[pick(socks_f)] - else - socks = socks_m[pick(socks_m)] + if(current_species) + if(current_species.appearance_flags & HAS_SKIN_TONE) + s_tone = random_skin_tone() + if(current_species.appearance_flags & HAS_EYE_COLOR) + randomize_eyes_color() + if(current_species.appearance_flags & HAS_SKIN_COLOR) + randomize_skin_color(current_species) + if(current_species.appearance_flags & HAS_UNDERWEAR) + if(gender == FEMALE) + underwear = underwear_f[pick(underwear_f)] + else + underwear = underwear_m[pick(underwear_m)] + undershirt = undershirt_t[pick(undershirt_t)] + if(current_species.appearance_flags & HAS_SOCKS) + if(gender == FEMALE) + socks = socks_f[pick(socks_f)] + else + socks = socks_m[pick(socks_m)] - h_style = random_hair_style(gender, species) - f_style = random_facial_hair_style(gender, species) - randomize_hair_color("hair") - randomize_hair_color("facial") + h_style = random_hair_style(gender, species) + f_style = random_facial_hair_style(gender, species) + randomize_hair_color("hair") + randomize_hair_color("facial") - backbag = 2 - age = rand(getMinAge(),getMaxAge()) - if(H) - copy_to(H,1) + backbag = 2 + age = rand(getMinAge(),getMaxAge()) + if(H) + copy_to(H,1) - proc/randomize_hair_color(var/target = "hair") - if(prob (75) && target == "facial") // Chance to inherit hair color - r_facial = r_hair - g_facial = g_hair - b_facial = b_hair - return +/datum/preferences/proc/randomize_hair_color(var/target = "hair") + if(prob (75) && target == "facial") // Chance to inherit hair color + r_facial = r_hair + g_facial = g_hair + b_facial = b_hair + return - var/red - var/green - var/blue + var/red + var/green + var/blue - var/col = pick ("blonde", "black", "chestnut", "copper", "brown", "wheat", "old", "punk") - switch(col) - if("blonde") - red = 255 - green = 255 - blue = 0 - if("black") - red = 0 - green = 0 - blue = 0 - if("chestnut") - red = 153 - green = 102 - blue = 51 - if("copper") - red = 255 - green = 153 - blue = 0 - if("brown") - red = 102 - green = 51 - blue = 0 - if("wheat") - red = 255 - green = 255 - blue = 153 - if("old") - red = rand (100, 255) - green = red - blue = red - if("punk") - red = rand (0, 255) - green = rand (0, 255) - blue = rand (0, 255) + var/col = pick ("blonde", "black", "chestnut", "copper", "brown", "wheat", "old", "punk") + switch(col) + if("blonde") + red = 255 + green = 255 + blue = 0 + if("black") + red = 0 + green = 0 + blue = 0 + if("chestnut") + red = 153 + green = 102 + blue = 51 + if("copper") + red = 255 + green = 153 + blue = 0 + if("brown") + red = 102 + green = 51 + blue = 0 + if("wheat") + red = 255 + green = 255 + blue = 153 + if("old") + red = rand (100, 255) + green = red + blue = red + if("punk") + red = rand (0, 255) + green = rand (0, 255) + blue = rand (0, 255) - red = max(min(red + rand (-25, 25), 255), 0) - green = max(min(green + rand (-25, 25), 255), 0) - blue = max(min(blue + rand (-25, 25), 255), 0) + red = max(min(red + rand (-25, 25), 255), 0) + green = max(min(green + rand (-25, 25), 255), 0) + blue = max(min(blue + rand (-25, 25), 255), 0) - switch(target) - if("hair") - r_hair = red - g_hair = green - b_hair = blue - if("facial") - r_facial = red - g_facial = green - b_facial = blue + switch(target) + if("hair") + r_hair = red + g_hair = green + b_hair = blue + if("facial") + r_facial = red + g_facial = green + b_facial = blue - proc/randomize_eyes_color() - var/red - var/green - var/blue +/datum/preferences/proc/randomize_eyes_color() + var/red + var/green + var/blue - var/col = pick ("black", "grey", "brown", "chestnut", "blue", "lightblue", "green", "albino") - switch(col) - if("black") - red = 0 - green = 0 - blue = 0 - if("grey") - red = rand (100, 200) - green = red - blue = red - if("brown") - red = 102 - green = 51 - blue = 0 - if("chestnut") - red = 153 - green = 102 - blue = 0 - if("blue") - red = 51 - green = 102 - blue = 204 - if("lightblue") - red = 102 - green = 204 - blue = 255 - if("green") - red = 0 - green = 102 - blue = 0 - if("albino") - red = rand (200, 255) - green = rand (0, 150) - blue = rand (0, 150) + var/col = pick ("black", "grey", "brown", "chestnut", "blue", "lightblue", "green", "albino") + switch(col) + if("black") + red = 0 + green = 0 + blue = 0 + if("grey") + red = rand (100, 200) + green = red + blue = red + if("brown") + red = 102 + green = 51 + blue = 0 + if("chestnut") + red = 153 + green = 102 + blue = 0 + if("blue") + red = 51 + green = 102 + blue = 204 + if("lightblue") + red = 102 + green = 204 + blue = 255 + if("green") + red = 0 + green = 102 + blue = 0 + if("albino") + red = rand (200, 255) + green = rand (0, 150) + blue = rand (0, 150) - red = max(min(red + rand (-25, 25), 255), 0) - green = max(min(green + rand (-25, 25), 255), 0) - blue = max(min(blue + rand (-25, 25), 255), 0) + red = max(min(red + rand (-25, 25), 255), 0) + green = max(min(green + rand (-25, 25), 255), 0) + blue = max(min(blue + rand (-25, 25), 255), 0) - r_eyes = red - g_eyes = green - b_eyes = blue + r_eyes = red + g_eyes = green + b_eyes = blue - proc/randomize_skin_color() - var/red - var/green - var/blue +/datum/preferences/proc/randomize_skin_color(var/datum/species/current_species) + var/red + var/green + var/blue - var/col = pick ("black", "grey", "brown", "chestnut", "blue", "lightblue", "green", "albino") - switch(col) - if("black") - red = 0 - green = 0 - blue = 0 - if("grey") - red = rand (100, 200) - green = red - blue = red - if("brown") - red = 102 - green = 51 - blue = 0 - if("chestnut") - red = 153 - green = 102 - blue = 0 - if("blue") - red = 51 - green = 102 - blue = 204 - if("lightblue") - red = 102 - green = 204 - blue = 255 - if("green") - red = 0 - green = 102 - blue = 0 - if("albino") - red = rand (200, 255) - green = rand (0, 150) - blue = rand (0, 150) + if(current_species && current_species.appearance_flags & HAS_SKIN_PRESET) + var/hex = pick(current_species.character_color_presets) + r_skin = GetRedPart(hex) + g_skin = GetGreenPart(hex) + b_skin = GetBluePart(hex) + return - red = max(min(red + rand (-25, 25), 255), 0) - green = max(min(green + rand (-25, 25), 255), 0) - blue = max(min(blue + rand (-25, 25), 255), 0) + var/col = pick ("black", "grey", "brown", "chestnut", "blue", "lightblue", "green", "albino") + switch(col) + if("black") + red = 0 + green = 0 + blue = 0 + if("grey") + red = rand (100, 200) + green = red + blue = red + if("brown") + red = 102 + green = 51 + blue = 0 + if("chestnut") + red = 153 + green = 102 + blue = 0 + if("blue") + red = 51 + green = 102 + blue = 204 + if("lightblue") + red = 102 + green = 204 + blue = 255 + if("green") + red = 0 + green = 102 + blue = 0 + if("albino") + red = rand (200, 255) + green = rand (0, 150) + blue = rand (0, 150) - r_skin = red - g_skin = green - b_skin = blue + red = max(min(red + rand (-25, 25), 255), 0) + green = max(min(green + rand (-25, 25), 255), 0) + blue = max(min(blue + rand (-25, 25), 255), 0) + + r_skin = red + g_skin = green + b_skin = blue /datum/preferences/proc/dress_preview_mob(var/mob/living/carbon/human/mannequin) @@ -238,6 +245,9 @@ datum/preferences /datum/preferences/proc/update_preview_icon() var/mob/living/carbon/human/dummy/mannequin/mannequin = SSmob.get_mannequin(client.ckey) mannequin.delete_inventory(TRUE) + mannequin.species.create_organs(mannequin) + if(gender) + mannequin.change_gender(gender) dress_preview_mob(mannequin) preview_icon = icon('icons/effects/effects.dmi', "nothing") diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index ab5b2b5f06d..d13211bc9c1 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -22,9 +22,10 @@ return src.gender = gender + dna.SetUIState(DNA_UI_GENDER, src.gender != MALE, 1) reset_hair() update_body() - update_dna() + species.create_organs(src) return 1 /mob/living/carbon/human/proc/change_hair(var/hair_style) @@ -112,7 +113,7 @@ return 1 /mob/living/carbon/human/proc/change_skin_color(var/red, var/green, var/blue) - if(red == r_skin && green == g_skin && blue == b_skin || !(species.appearance_flags & HAS_SKIN_COLOR)) + if((red == r_skin && green == g_skin && blue == b_skin) || !((species.appearance_flags & HAS_SKIN_COLOR) && (species.appearance_flags & HAS_SKIN_PRESET))) return r_skin = red diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 59ff3b11fe3..8b6aa777d49 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -212,6 +212,7 @@ var/list/allowed_religions = list(RELIGION_NONE, RELIGION_OTHER, RELIGION_CHRISTIANITY, RELIGION_ISLAM, RELIGION_JUDAISM, RELIGION_HINDU, RELIGION_BUDDHISM, RELIGION_MOROZ, RELIGION_TRINARY) var/zombie_type //What zombie species they become + var/list/character_color_presets /datum/species/proc/get_eyes(var/mob/living/carbon/human/H) return diff --git a/code/modules/mob/living/carbon/human/species/station/human/human.dm b/code/modules/mob/living/carbon/human/species/station/human/human.dm index 31700054c0e..c186cfec836 100644 --- a/code/modules/mob/living/carbon/human/species/station/human/human.dm +++ b/code/modules/mob/living/carbon/human/species/station/human/human.dm @@ -25,7 +25,7 @@ name_language = null // Use the first-name last-name generator rather than a language scrambler mob_size = 9 spawn_flags = CAN_JOIN - appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR | HAS_SOCKS + appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR | HAS_SOCKS | HAS_SKIN_PRESET remains_type = /obj/effect/decal/remains/human stamina = 130 // Humans can sprint for longer than any other species @@ -38,4 +38,6 @@ inherent_verbs = list( /mob/living/carbon/human/proc/tie_hair) - zombie_type = "Zombie" \ No newline at end of file + zombie_type = "Zombie" + base_color = "#25032" + character_color_presets = list("Dark" = "#000000", "Warm" = "#250302", "Cold" = "#1e1e29") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/ipc/ipc_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/ipc/ipc_subspecies.dm index d2ed0714780..b2d3143fcc3 100644 --- a/code/modules/mob/living/carbon/human/species/station/ipc/ipc_subspecies.dm +++ b/code/modules/mob/living/carbon/human/species/station/ipc/ipc_subspecies.dm @@ -43,7 +43,7 @@ "Your synthetic flesh crawls in the heat, swelling into a disgusting morass of plastic." ) - appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_EYE_COLOR | HAS_FBP | HAS_UNDERWEAR | HAS_SOCKS + appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_EYE_COLOR | HAS_FBP | HAS_UNDERWEAR | HAS_SOCKS | HAS_SKIN_PRESET has_limbs = list( "chest" = list("path" = /obj/item/organ/external/chest/shell), @@ -59,6 +59,9 @@ "r_foot" = list("path" = /obj/item/organ/external/foot/right/shell) ) + base_color = "#25032" + character_color_presets = list("Dark" = "#000000", "Warm" = "#250302", "Cold" = "#1e1e29") + sprint_temperature_factor = 1.3 sprint_charge_factor = 0.85 diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 50e66a0a12b..bf3a34982ed 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -34,9 +34,9 @@ return 1 if(href_list["skin_tone"]) if(can_change_skin_tone()) - var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", -owner.s_tone + 35) as num|null + var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 30 - 220 Dark)", "Skin Tone", -owner.s_tone + 35) as num|null if(isnum(new_s_tone) && can_still_topic(state)) - new_s_tone = 35 - max(min( round(new_s_tone), 220),1) + new_s_tone = 35 - max(min( round(new_s_tone), 220),30) return owner.change_skin_tone(new_s_tone) if(href_list["skin_color"]) if(can_change_skin_color()) @@ -48,6 +48,16 @@ if(owner.change_skin_color(r_skin, g_skin, b_skin)) update_dna() return 1 + if(href_list["skin_preset"]) + if(can_change_skin_preset()) + var/new_preset = input(usr, "Choose your character's body color preset:", "Character Preference", rgb(owner.r_skin, owner.g_skin, owner.b_skin)) as null|anything in owner.species.character_color_presets + if(new_preset && can_still_topic(state)) + var/r_skin = GetRedPart(new_preset) + var/g_skin = GetGreenPart(new_preset) + var/b_skin = GetBluePart(new_preset) + if(owner.change_skin_color(r_skin, g_skin, b_skin)) + update_dna() + return 1 if(href_list["hair"]) if(can_change(APPEARANCE_HAIR) && (href_list["hair"] in valid_hairstyles)) if(owner.change_hair(href_list["hair"])) @@ -110,6 +120,7 @@ data["change_gender"] = can_change(APPEARANCE_GENDER) data["change_skin_tone"] = can_change_skin_tone() data["change_skin_color"] = can_change_skin_color() + data["change_skin_preset"] = can_change_skin_preset() data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR) data["change_hair"] = can_change(APPEARANCE_HAIR) if(data["change_hair"]) @@ -149,6 +160,9 @@ /datum/nano_module/appearance_changer/proc/can_change_skin_color() return owner && (flags & APPEARANCE_SKIN) && owner.species.appearance_flags & HAS_SKIN_COLOR +/datum/nano_module/appearance_changer/proc/can_change_skin_preset() + return owner && (flags & APPEARANCE_SKIN) && owner.species.appearance_flags & HAS_SKIN_PRESET + /datum/nano_module/appearance_changer/proc/cut_and_generate_data() // Making the assumption that the available species remain constant valid_facial_hairstyles.Cut() diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 20138e11e76..46f028e602c 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -21,7 +21,7 @@ return if(!isnull(human.s_tone) && (human.species.appearance_flags & HAS_SKIN_TONE)) s_tone = human.s_tone - if(human.species.appearance_flags & HAS_SKIN_COLOR) + if((human.species.appearance_flags & HAS_SKIN_COLOR) || (human.species.appearance_flags & HAS_SKIN_PRESET)) skin_color = rgb(human.r_skin, human.g_skin, human.b_skin) hair_color = rgb(human.r_hair, human.g_hair, human.b_hair) @@ -33,7 +33,7 @@ return if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && (species.appearance_flags & HAS_SKIN_TONE)) s_tone = dna.GetUIValue(DNA_UI_SKIN_TONE) - if(species.appearance_flags & HAS_SKIN_COLOR) + if((species.appearance_flags & HAS_SKIN_COLOR) || (species.appearance_flags & HAS_SKIN_PRESET)) skin_color = rgb(dna.GetUIValue(DNA_UI_SKIN_R), dna.GetUIValue(DNA_UI_SKIN_G), dna.GetUIValue(DNA_UI_SKIN_B)) hair_color = rgb(dna.GetUIValue(DNA_UI_HAIR_R),dna.GetUIValue(DNA_UI_HAIR_G),dna.GetUIValue(DNA_UI_HAIR_B)) @@ -150,13 +150,15 @@ mob_icon.ColorTone(rgb(10,50,0)) mob_icon.SetIntensity(0.7) + if(skin_color) + mob_icon.Blend(skin_color, ICON_ADD) + if(!isnull(s_tone)) if(s_tone >= 0) mob_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) else mob_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) - else if(skin_color) - mob_icon.Blend(skin_color, ICON_ADD) + apply_markings() diff --git a/html/changelogs/mattatlaspoze-newhumansprites.yml b/html/changelogs/mattatlaspoze-newhumansprites.yml new file mode 100644 index 00000000000..a3a0b1c3e53 --- /dev/null +++ b/html/changelogs/mattatlaspoze-newhumansprites.yml @@ -0,0 +1,41 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: PoZe, MattAtlas + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "New human sprites! Your characters will be grey until you select a preset. Please send all feedback regarding human colors to MattAtlas#6970. This is brought to you mainly by PoZe, who did most of the work." diff --git a/icons/mob/human_races/human/human_preview.dmi b/icons/mob/human_races/human/human_preview.dmi index 961c062c2b23adb393c2436527192d8ee14a15da..1d5051bcfa7ad427e82f27ab5412efe9280476f0 100644 GIT binary patch delta 267 zcmV+m0rdXv0;2cX}mg( z_V2$Y$=}7dR5R2RWTB6QN$oMTw;`j;Z#wQRKB%I zmzJ=vOr?v%a%! zLG(Rlh9@~0!`qz#)6))6{Xl{52XaC%^{M;`+%yu!fWZ4fMkX+h^?7`J-Y=SlCDOe6 RNaFwi002ovPDHLkV1g*kfg}I` delta 214 zcmV;{04e{Y1MUKlBq113OjJd{z`*jDHUG+$GnoMQy?ynuXaA%~@t8K1mwCgHNPvHo zNklZ6aM`sqNLGNbno;bTeUHeF(xLKV=qP$=S3EcCxEg`Y4hnp#xBzE z1t9mm*!)6DpcvPt__o`#uWO2MGTM9Kbbp0NWVIK)zdk0;w()`J*T) Q^#A|>07*qoM6N<$f(C&2->!Njz<@$#3d!D~jEvy4Xn}AN0K_-T`KkN#^n9jvS zW3Ly)dp&j&2--N(q}A59W#x5}!$W4kQ{gLICN{dqyjQ4AYER*)vrxN#yW#O<@w>v7 z?5%pf&PD|$HI|Fdif_fsF(T^J{$3$;n8z>1mYlOqP@Ek{-Hw=B(7dgyR1SU-MPvG- zH^kP|0|7zYiH3UG*5U8grtks0U6Bmy=vhCJ$M3~ALWt2~9zNC=h2Dj1=4nM`MQJH( zMN2&8?0iCOJ2y&UJfM4wwB%gGHuk4A*VK3R&_9$uZxL$|s4S@Ee7<&~Iu>&Cxf<`5 zqS+>}$*&NpeXJoz+|GEdFV$FG;M?L6*q-r37M8`OYb~`;;8SKh1;T@4&T|GfNnlkyAbSiGCinEFY-$vGUTX) z!l`97chaKFC2~u-SxwycqLFVzD)>DcZ`P^Y7C}X&B-J@96!qiZ(dLScg$kPYywiR* zCc_KelkO+|%Xo$=B@Qm#gqexE>7`=}3Dfj3Sod&0RYq_MMb(?TJR-%Cl~zt^N*Br)-$%BY6hg*ayZ*LChzk3mpyK^-s>jA;Rw4=Dhw2##hJvn%yf$*YWI&I zYqnn}@z@VK_^bb%m_Fu)^{;!@YRx03r}_x&8yH7T73$^-amyfXnA=(jkxWvfX3(1Am0dBi>43SyW(g~}qB6F<=K z?OHDT57s`&GH3H8f52V2c-z$=P(>TM6XOh;J={>FGIhYw3wRr1?KSpt0*4 zwjO)ZHoj(B@$QppYfOmVx1+{#)04=o{Do6Akc~J0kD4nX-RG)%ncmIv39nqou9+&> zDncO_&Lt_7rOGL!yf$hv>U-$$3R~!`LbqL>bkdIZ-I}@f<`mt~G2gs-r@VOx0(mgj z1cS^r%?d+jvTh`**nZl*7Am(ikE0ub7h|9Qq82?8(%K3EWMkN+1W_AFuDlg3PDW5x-4i~6Y1ieAur9L8cZ2cK-I8CL zje55O4C5lzbnq}fN`ePgI5B2ZTQA4hwr_av7v0n8=NN3EkWcYhpiejn{N3fiv=IuV z2NHCZIB(##cmH_OVr^HdlJz}2K|O!JJXZv!QQk_B!rrZV7d(o?ci;_MbNv zK_QM7pg*$zTLTCh=lK+?u~al%pR_6E3{p!8xqaI0j*e81?rbuU zUEme|AD)3#D4bpGl!$c*Tcu&&ofW~iUbTx$?E9_$UzS05I<69%cIb~<_|x$p5(+!T zzx6i2E|gU>NhqKX#SBOn%pn!jJ&o2+hgfW3j^#xA*1mdaQsSJ6>ACzND5|~8?@z8w z>>50{QfC}5KORAfdL^fz5Wap)gWLTDD@~Q%m7fl}KOI)kS1dN?j^$Nd+`ZW_>0Uuy zzx7Wv^MU9-z5GHB1XhakC28d& zkeb;ZF!5zPiX8l&`N;NEGG2d*D>F_s$M{end{C#r+P-;kL!iN%PZ?zV>zX@Q5_)Ky zPAF&e=3^2UP3PoIFio}Xy21vAgI}%(c&R7BIwuAn3_Xb1I}xQx{*9r59(|H0Sj#x< zEi9$Ps7i84kDPF3i;s6$2`0P}tc|Bc-ks-7#Yq9@lOm`@Au}m3h8yqsZa*C~>doFv zXS48Ws3%mO*3t|4vZkY5#PvkB${r1BWMlShltX}+Y|38}g2SA@+0Q0hWA{|VUl%gS zcGc14u7-CFlL#O?Gi|(f@)>?4q%I&GP;ucKSGj-~_)1stBUfF>XC8_P!Rxn@=x(H) z$N;HQ`w~R`VjG`=GVQC^MlK-RE$5v*AojsLmM@5*@XAP>W`q26Kh3eb82M|)TL!79 zsekU~p(SuhjHy)WPE#eArzmy4A8t2?_?J@aq**z9sn6FyW}gfpvz_w>qp&IajYKvg zwaj_PZGn(I+LQt_5VFK6AU4JFhZgzyh-heg8vVd(4EV6O%C&32mo_uFowiRX=SV<3yK2Uo5;o99Q&5LV!o zqt?zB{0d|1vLM!SdpJ{U~1ga=wvdK@gJ z_k8=>HO;h|JIL8hkb~?_fEGYa0;&n$nyQ1Ml%^Y=EKLdl{3IM7!U`ygm6J&K0m%t9 z`;8`5j1HVnEuq%IAqXfVGjLPaHHGRm#Nu54WObxFvFq>PS$F?Q{!jZ!w4KO5U4)le z8LF*$-NZv4vznCUpCy@#qKDw7FMLsW`H!MK>ivdf-Z%WAAawytK?pgWSD3v*O*z-z zaaB352-~^3UT@TepWv~R?xC}r`l@#h>D<9NtLk=#IQI16$S2+NRul_lR8DPWfq?u2 zJ4U0k8r3xRCv37EW^)XFVR}OIGVrE5$v!(FBH~AyzpG2oWnVSF9m-N#f5T zr;BfMF?^r!X?Q?mjLk+TRz=`%Pio=Axho>zaza4X=M*JMthPSb2m^B%&{UFDshPq> zv>5f)A*5!0M!SUEG*dsf_&sJSGjYt%MpEqF!ir3f{l8SF*4Gq6dBa**F z)4iv5n&KGl#R?2g%&C(4zSbJL$42Qnx+TJG z!*;;xyU7<=a%!f?c%b+o9dp2Y1lq#v5-O;bK#m{?6|n=49&wt)3ViEA%>6_A-OFmr~b=)y1)K@f=I;pkS*z9Ho z@i94ZU;b7<4RnG#LhAwxPKva$%ozuyG4h$i$0}l&c}3IAG*}KGMJ}1Jn{=o(&1z4l z=k;V8j6)a1Z38=TR@pEjAtrrlyqHxH&v^XycHct70+4AjHeK}{1>jr1yIOv@p{p;f zxIhJB671D$syE4XU?K-!w-29uU_3Aqbwg^Peob?=po<7YkRt0tnaC>K0jKx2pSAps zvz+&Fv#zqoXU^i1%`jUvYpTy#Dq~{jkiC=DQy9iaRnx#xZ4D-LDIQUwo;HQ^SbU9g z4PJh1g$W@LG0T_?g!_A)BKggX8ta!yCk8BBx=Uh^vR8rOdGNUzKI=&=2i^^6s^ z#9fLF-;yBp6kD&G~41&HT<)}VS=CB(qQHw_L-Zoq0oTUlU^I~f|jO- z_hxGFvN9tB7FDA3JvniI^FXAW^rD4q=J=Z-uE$P(A+12C$WM;vJFL}7% zlyJYk0UkhRTRDk#dZ(Y>UgQ6#`vzp%FP(u{AUz8Q1AU!=*)J2yH8AOCZ5UjQ6zq-L zx(c6kA2DDvKr!f}WGqI{ttRR{^&!*!*E0?G$rxA8J1lyOJFBYr?$R;&@nra%cT%ju_%oKGDHubfhoy^v=i9a}gn z$#KmKJoqJMKNNpr5KiF%j@D0E#s_i_t=FYeLx`?uB{nM_|Js%dhN{?vr+>}!Wy#n<_la03-Y5#>-D0440 za=m}2rJJf5x9v-HQ zrF^*0zbR*X^Me&n9Sl-S;b;aa!P#}1J#zscc}$RwfL9lx|D3cwN$Pwzd_E*U#{JzA zZ-b}?I*c8kCmx`Y*ghJerKhL;*cAYdDBZtl=65LK4;8EBzbxe$yze3X)c(49M;xBR zIy8qA!z9}>`&vz)-iu|Ui~3!I)J2vy6&fVVmyRseKiM*TDcwNL>q*5?hvr~4)JS;D zJ+UjKuU5exRB@4nsJ~8GCTpROsVKh)cBk~mJ1rL1-7LB9a z3l2(CJ~~eErE1^sLQSVS;uHqarf7Ee8$0!R_ZqH!eK>xy7c?kY{VeQ+)@m@JlYnJ`6Zr0X=qJ=!*_@BU;&xEuFIYG>(EL15a+mzcfpoe9;4 zsAxIyFy$>E_E_+qTkco5v28fx_IqY@jM6|vy+JTbQzQ7KuLanz5J!Qqdo~_q;MWr5 zneqc#ml%g`!B_#jl&Wp)-HdQ=A{IWiV?WK>@NA4Sdh7XGKVuiz+W}bpzt@WWr7%5W+RgVosIQ%v3D z5&5OfD&`}h)Y<;Z8I9+XnK}Jo5a3z2y!pQUNu%D=%-Q4zF$mO5!K0vtIh3_zd&q9S z`M1M!EHk;zvhxRTx;F1vQSrL2tWyd{VzF;51(?h_3~F7DMH~M z?cxb|W<;Xt$<_0y5>`BBo=Wc(h(fOD&Z3Jeer@NCW&v;kP6Npd(Qe;g%7Cpe&tm?H zMOEG4a96?VBH%ZgoOV`vZ?Jg+06v#-`SNzzKcsW=&8>oHn^hrP25dSKX|fhO;w&qA zXWTfsi*(L*YmH=PfB&$tazAp&E<@x&ZdH#vnHIx4{12yrM-nOdLDe27N~Gf&E)oVRhJHC;6N{kR^)-vJ>=z*-6(%g%R+oXqhW;k&L*X{b>fH zE@u|k88@%WB)u$U6O3%OpKtfDJsUcXW;K2AUMb?eK)gsT6TD^J%H)`=ev|U;yGQI` ztS#^WmuWiMKGq7hMyxT0Y(D%hk0GHL>l?<7y$u+0uWqP z4GkNNSAFm@5>I6;NDX?ki5^jtB!LdGML$umd%My7haByIE7+^7C;mbUe9qjT6@#M8 z|Ki%n(0!um44hgPMoU@L*K9UN?fn=q(+b!Xp#HGmZ=p8sO}RiA#6r47k3dL7M4?6v z@|0!-;pj&A&XEpM z7vzz?5y=^&p0#o@NImNg-(S8_#Dj!>!NKc#Qc>+2Q480a^m2cld(F1TuydhBRHmN3 z4kt89_oDTjXW#F}tb%xJD50f^Qj0#*k^M|G@G&Qojw`K!H@gnTWIFf7+lw!nbhYD$ s)w7z~)`R5>n-;tueR8e8|HV=DR)4BD)e^?;HD`t9MbR1*;1Jro1h5!Hn literal 8613 zcmcI~XH-;8*X4zlAW=nfPNJk%K#+_Gf~e#M$si~>NX`uif*?U8$U_DZXriPhBO)0k zXXqy9oHJ9r-#2U4%z7vM_~u79t8ZVb>ee}D?|pXlM^$A7QX)Dc2!cqTDaxrs5Dp7? zL4^3=3I#l`0{r>usrkxT?v0bFqosqhrM(>lxhIA9ND?*OC&8NZTPd!GjB;YM#{4_O^1#OVbOjfJv#0j4(=!ne~dz-_)4 z3llAGF>tBb z_$bNWxbvFxopJzvjrfHki*rDw%+fVWOZJp)(H(@4x6X*1HTYOdi)zVEt?=VHd`7Qxo@PfkdQJH=;mi(5*D_;4>)piWB0*L zi6yYMPYQvFl<$=42At{~txro0hO!9}^AiA_gD(oLbmnuE8K!k(|z+LEco&nW`L zfA>v{TW)IM=YwDC z;M`uN6Ihv#bgC&dUa$kwLG>u zEJ%Byj92EJ?0F0gWVszU8~C!sNfNHR$|ude_3<)S2}`SDu9E92U>m~YYMEYnccw;- z%%QI<&2FyfZE`6u63*ZIMjIKjirnp{c_#gnSWW(+3yNsoh=tg8&4v`0DK{lK)TP{x801RtZYj4gnd! z=X$~w*k4ps>k0@V5)C=0sOY&Mt26nm2r8z+m!*!BV z>#y4(Ir}$GW)6*T3syQhIbSR0@sNR41xXK(rfsp3Ko_baeIMU(p8i&nT(uHoC=AC5 zFJF6D@`b&y_F%vsNy-=uD`%3DVZ9G7Mc6Te#~5w@T)l*oYnS+9BvQN^jbKR4zjW_g4JC6a}Khf=iGSYvp9SwcUeBt3%4L=!6Mka zF=Ry*RE#R46y(r5ZtpH(ICty8YUk{>7Nr#A1*-Sv)!YB3g#U|U`fm_}w3}@tVN4B|EMb=-*jdkGIb~f9atnox+7S?UamU3V z+DO7|?s7V?V+SROSYoK*7My<9$t{#g13X()VpXXA0%oQtA&)y0zLQhl0BSG!;(FF5 z+HrkP<*qF(TXPUrBI0>RG-$zCyyWj-F7Ka4SF>mh`TeS;b?sZYSHrzsGcj$g{t&Y- zA>pqz(Xe~U$*euEW`Btp?SGyB#{SQqFerTDqng;5H!bYHhDBBPUO5#rwvTM14q)tb z;bI68bu)z>WZ2rD2fwR7kbtGub9udcaJ2r0HX3is^WLRMZzk<}m_Oj@W8AuE5>*1Kx`6g>8fP%!GJwYd=X zB2dlTUnH*O#WumGOlUwtsEQIY0+a*5cyxw2e^^IG-WZa@Ca@H+;LGC5kXkTZJ_2Jy zMHM;8SlXL%K2MHSZ_E|&p!x)`oc!Mc`u~q?7k^SPbv~aN5d2Thuk}3=&bC;&^6&XcHMlXikG%8t z-K-yCRCgIIzXj^?iRzCm)U*U!0g8+T#MFqK8G>vk2j*S{p$a-Z`Rzp=@9Rc1-xy4M znEC-ONuN2UZXP(Xu*#5=aHCJ2$(N!a=w|p+mtp@L-h=0ml_i7n5Kl6V0{=}7$9sWm z$KNStRehd?fNZyK3zQzHTc~&?Le189@^>^p^Wl=8Q2rT0t^aPm!F)PRFomKUdQoT20PgvqZ8rKD~*849JH0VXf zQ!m;pEC6}(e}jC)^`NF-7Y12hDg34@wC;BC&Rb6OeA2Vg50 z7qO4Kx6&-e`?G7$Og9f_vd-{&1tspLVEVK7T8ssmwgG-_9ntSXJ%SQBe1T@8Oh{7< zkPWnvcSlo`ZIFi7Us8TPl$zJ*A2Qv+e*uQH!v+{P;2AdwB7;82&@a3#G`%qLy)N@- zoe+MOTHJc*Y|meLF8-BK>^ihn%N8?9_qv6h4OytF`P_^-I$njv%csk0z9`d!@{RcD z1qlmx;`s;F({Fo@$}4GA*z&5}H=_rMQdtx4g%(OJg>1cL+b2e@;JlVXf0%JO%cYGY z8vyC1)e(#wU8Awy{p7wb0zBc}``+rlYkR#_fn2GI*eRQ7T?JKEMe&Y$i4f_pudXbYzV}NlyNVHA&;Fysz zss6K5K|c$5NAtg_f>E7+O?)>Z_VxM2&Ck7jH^>}EMd!L{D_!0W^or?A3x-BwrL1E3 z@dl=lwM*v5wR)0iwwb|rP%SYuGc7g5U<2nR%~IsQ$&-SoL0C&X6&e3m%uuUp9q#2H zTOkb#(TaKW=tF}Jq2H;|i`N?~efB$5dFJmf!=8Dc9jLXsU1$nfLB&+kZGSL#C0KXl zr9sKXq3a-CBS3QuY_)E04RpYF z?dPjb!=}rLytX$Rl;_I)PUIJhhI}W|b|EgLvG&cS>KjPDGPdJ| zFMX+JWm~Z{1dckOB8E&ISt|A}AKmlXjV>>xP5Gt70!Anifmb2s*y_JSknut1>DDz} zAcoje|M?KwKLx}_yK)2z_`uZ@Itt&^bFsSYw|^D;d-v(9ULoz}oXK_IBgnIiNr8a)9F7o-MD3IVv|_!Ud3BHPtdn zBvPZq(b)Of*w>KS;2KYfox3Y~bslIei?h;U&{|#aZ3*M|Okp$T#+ad_Gc4I+g@FX` zcj-&q{#2w%a-1Dm1+~G~MPd6kUa@n&Rrb{!6w_hDSKa}0)Ljl?WjLMm z(`io*511MM%_fk(rWu!n7{^iv2t?20wx_6+@w98841M7~qk8pI9T3>cAveN5{=%n} zy;2Y+NUXXAb5X)?ZHdHuQlh*b*u*wJ<07?xRp*OOFFz;M-nb>plJ1@u_{+ou-Y|P6 zjsXgN*vnWM-H?~PW^wK@&_n%9E(W0uBx)cQ)#6b2UG25=4fD^iimjaUxT)@`*D4^tpx zuQ+N6!z4F2rE?!F_I=NP3ef4;9+wvpr%R7cvr28ej-yvRm-w-U!JhnyrZO%azIR>> z2I`lqR`41b2C(GjD=gDlR`WOYj9$>Ecu}UbUQ*VdWv4%k{R5!{vv@R>P?*5C5^T7W zUM4~kNnTHtRllRWMd3e4SUm0pgj%Ps4I@W$iPHCnE`ZKr-_d|uY_uXP&+b64u!t@q zpdd1iS8GBs-X&`bMVsoLmVkK;UVS!Y^{)3iw?|NhZyH|e4aYU=e5^aaoN+X{U_7of z98U!ceY0x~>H+vfUOW%%lAk=o;9Q5uV{4GnX%C{Uo^)Fe2U$mx){ z6Yw<-yZvis(3$ZJm%Jp)=&9OcWxs>YY%C6R_IB29zmiCl=0>~TmaTi2C$G30^)dH& z1B$7q-C;zj+HW0;3KEJd$Rq-_RFi7DL>(E29E+$F;h{Z5-!#|v_<%xHzbbLYc zn=m)f^lU5jIIcwRo!RN46M0l}jkV9b6FJK65{0`2aNqqN^6?%Cd1&_Go@Euc&c=~s z)B7=5#kd0Yz<6c{Z&V`}iE1+?iiJn)T*ji=~tjl2L78IKo##rr;TYY(x$ z0)*a{%Cn~Jc$*1YutO3-Tf!&3W!u+RJ42gADiEG zU4n!;?f!$~M4#aMy~u0erq^3t7)lWTYrOVR-> ze(Ri(dAc-zfl*?qGmdkOdgZCyJP(iGoZNsT){!TqtJqO-ktu6_{aYzuMhE*}>oY*w`xliu9M=>bKj876^Le&&|8t0z zw%V0{@V|1KvzT8l_QJEhb(a%OP-$6J5|>ARlh5|0TT^GLD)+|k^4)8?1&zkf=8v9( zFQw!(6GCBkMVwsP#qH}@HJ%ZUlD{*P1pV5Zy8BhK!F6j{AToJ*7Ge>AIiOF|qoo8< z$}jc$*`Of9cBI6k4?b$GtCegXJaSsLKLE|hY1V~$%H&!M96cb){x$z6-tlGe#|w7% z&Mc+4=&-Ga1mj@4Tg&U8C~Y=|0`)KqSZIEHRZea`Z~UIlx`r_aRpEf|?Nu4g?iJUk za#c--py~p@ivhz(LyDBJ*Hax0;2(udib?r*j@*Gj)5jh zVD=_RoFO_B)FLc8jH3gN(C{Bg)~_UA`}Tc**(Dwcyd^H``a+8de6h~#@;oagt*W!| zqz^*LG}=_Mjyn3{$Q(UO!eo-*=7Z=>?vC>K1~}bAvtyLo&o9%(l_bWg>-hSy<1%sO z;PQcdX3LxA`7cf=CRlWyOdBoE<;)H%*J^o2d=Yc*$13-V@%p?8oVf_NTYV>rs3O)# zH@Gi|ZBnzkZhb%fM1A{DPDwmiuDr&Vj*pEKNeQY6}9F8k-J?e z_z)ByDoyY%cHF9iql^&yezmMly=;D<)t?&cHX!u_J(It+v{4!UE6{J1aHGsNJ+}JM zGK0eItaJ~Z84lv2ogN1X4K!V#354tjxGoM*LwI^t!QG(JUi`@~m&#N6{+5c-w_Qfl zIs0r z6OuaM*x@s3`p}x%;=MxkA81I{y_W6naQHpi=V$$8Hx>XY(w{wKGng;h2}K4fg#M`Ie{O@kH?1g z88uAhQ)(oss*iYg7C*_Sn;OMHcLUWglBSO;RsRKxf>a&0rN7KK4zeN0K9d;?15Itv z`HVj$CpKDy?Dm)&6N$qFAnO{E4>)B+RZX#iTgzICv0lCDsHn2w$PHpP7u^l@C^ts_ z#ghcJBg{yBPA!1Mu$3>$pK8Wn!1pa^*wn=~J-0_0(8S=Bh4u*==A9Snx!hgcN9-%E z&By48aOINKxT(?1w*AW_Ml+!!VZi(aV!mlN)WKWtTZUSb?~tg7SLPP^XZQu}D`(d+ zQfVWQjzCg?d|E}CUiOjhzTLUq8POQ#~X_$qTeH33(K zsxHZ+RIkB(&pE)O6VK&-(Qg6Tk4(qg*!S{IiJ6>66JV zVfz5-0b5DnFF4pj?zvtpyX1ZH(lt8u1_w=@Z5R*t5%Y!zwPg``U`@{!$+CCv=V;-l zK1chbJb6X7@=q|oL305bQDZ3|J)HzSk%z3OCesU<(rXt`f{Jg&lG{J;*C~@fnu4`d z(MukJGEOecO4WEb=4&KmrN5*r^=YF1@u1X^&7~gVTBEwDgB_NHp5*r5N3j@uj`r61 z&8lV#?pojXNaEUX9HArhZOM&_gnAOYWLi9^?Kw;dajS(S4H2_3b?j}JL=r47l}er2 z&K2fcamkGKyf+`ypjkKRD8N8fWK@}!rGJWDbDfIwO8l&cX6K`{S^n*=)38`pA?X7= z2lU$R@qqIvtdAs(sP_+S+|)vT{DcC4}ZGRwQl(T#D5Rn>F5JMYk&tue4aP|seS zJ-?^am!tr$9^E}Jp6LP_%IL}SMQT^SVYvR!--QN8MvOm^;>#Dxs$>14<<``GvUfcs zm^fLZx)+1a#yJshR`Z{*Fi^o$=w$8;)GQG#0a8$`q6q-{wUChk21(R7oQI!(cK{R| zd=fbYB$tw1a}<@q^^|`KEvy*uRVn98f+uj4*T=HT2vq50{Z63b;U@~CVk<1!_3qmP zGlG)whRp9C`h5d1?7q2Z&+6sW<=J&;2ES9kZwjfZ6F^tSvDuOSs(4_}X`Os`JbeJ@ zX01{1Ai}^V*+J#{q$X2&%$xH18OM-Oy6nr->~bWuui?g|+%|t5(yb{H-3KBMa1cNF(zN@rYr_ z0Ix43*!cf!U6+1`h=5VG>{85gZ~Vf5^AztRPPq2d)v<$v9bmVu=pk^-fH`!Vj9B!6 z%UuR4?jiP)c6FaoNd#|kF96g!*D(Q&}X8N@os#?wcJ>npHKYIn*sr$hQP7ws! zbAKHM-Egqx0w-DE>`YJE+@||VGt_P+(K=<5m7KlUp`!B+qP?WYwT1jzrnK*4&u9XS zE=3As?TdneW%3{Xwgv53L>#0#c~K^X@Fsiu3X-L*6O1IAzB7wlUuWX9u5 zCapCy=?e%1M)-nMt%=hfn?$=Sh_LkI)Um@;aKmf-U^=k}8!PFmQV(s3l9DlCRN6$a{hkoP z`1Zgk?CA6EKKBm4pJ@>xfaOY&V`3Wt;$X%U86MEYf_<%|7WeZaB`@e;Jtdjp@f}gbfn%k0dgi(1Ik&jqTsC&-<;z0;$2D{+X@f+}kQQMT zqg08_5n5N8o=K0OuL1FlG42bnu;ZFsOnGy(z!t`bk~PkaQr}Cg(mV29#4lkstWXZC zX*cv;Hth_*Ud0JqCm}mc-8+z(bS+6OPTr!Lvun?g_&Z&`GU)<1I53^Nx6}v3_!*5r z>KVzEAL;iiLTw{sZ%~)tOf$IK`$V`loc?}leL;Q~ARnS>*c5q>4o z^BJq$b4#Clr#Eb>81++9>RsO67W7HrM7CaUl$rk2uP(`QI=gc?@mh$|u%WR557PqC zo#}-#xsAUt!Uw09xbBtf&#P{>RF9_)WtWgOUK#7_xt7KW$wr2h;;=)EU;6-w_nV6p z`T+k{>T{PJ68+`Ps+V?~^B}+xWQxPGASjwzbC%IB^SI(s41`~51_lbFzD*6T!0W* zO|m&0M@eM3=&{t!9f>iNA$9(qZ(d*qBm4##F+%*<@kHwUB17;+rqOAApV%n60cG2u ze{7u#gDv$|d=I)luP?;h;1e@x_Yz3apu+V{IpBOT+3M5Amc51~#~yJB{o6DCOJ=MT W>nlQfIzg~L=$X8-T%oLSz<&dPtg&_g diff --git a/icons/mob/human_races/human/r_human.dmi b/icons/mob/human_races/human/r_human.dmi index 5724355bf1c83196ffa46f0f81b1e19bf11ff641..d870164d3839fcfa42d5d6190ab288dabee24008 100644 GIT binary patch literal 6347 zcmcgxS6EZqx?O;PbP!RL5~PW`DN;m1q=*QjAVm==p-7id3?MZKf^-DkqA1NE2_m2( zy@V=i=tUF^p-LwhT0%&2C;NQo z&=P`Jq`(K-&jEUbl}oC?SACfEEu^8_J=Z`lf25Zm0)pTqOji>+NQa2+A+Q&VyBM~eui7vvSm3OxEP`P8Ps z?Wd3znVv*mXJJkMJ8|45;_GE)Y9{IBD1pE(l=1Krl09L5)ddpD5akdQN_7688_$c` zJQaOI18&NmG%22INb;doILr-Nv)tL*ZoC_+v07&+ZReP}DfI(egVqgrnt}XDKH0^H zDjaiH^p$gGKA9jMXZBNYhAUYxzWmBhvm%lRmp<$Qwzsr)&O?R#<`(WWVZEaLt^k1} z^(eQ1rpy?_#|y7UmaCcbuxKFIA6558uT0nKa*fD8Pv>~-9npzc1cT27^P~}y78+lo zRl_hh|8kSfan-yGXYFtFi15`C2*Z5$q{+^ny@BA}Thr~(vv_Si9J<7;dO*9e)0OauGWFlYMj=lDp`($aTz;do-M{U-=-NQyh#qeVw#F5b{sd`G)r?0 z^}`VL-JQ9Tw_zP*#(F;Jrf$Df*f2{Iu3(zjHZb?Uh^iNot#@? zCs&!1J*@DyK!VBQYTZ7SvO&>5iRlgc;`JJTa6$7qxA(?*B97TPva9f- z#~QM{aaBQ(OtrZF$`q#l-$VJbHU7HUg(U_T+G#%wkK)+gy-Mr(&9AjL*jK`-59{2A zy|k5^EFv81jwBsEPVgPlt~8>#RtIA%mqQ)i!ND(;79%8g)!o@^Xesli?{aA4lj%NYE{ow)l~w8sq=?ZkeNLk& zcB7_)i$t~PgafS$0?O}uM?LL+tg(pd878WlHs&crNIS4dXFGyPC~Deb+it~ScR;G> ze6oL!>Xii8FsX7L0E9q7LOX~AV_vrZs?gR%?ZiJ-cB+&Rv9=ev|*;`s||yIrHjXl|*LZP(06osa4SRpv;NfJg-xx68@|C=+dqLF!7ZM zD;4O=oky6Xu|~cdiV7_{y0Na+O2Z~GuGOC;Q!>ZIooH4_M5IuiuLJ;&@8g>e@1A?w zaiWQGixYFXc`Xb0%_~T<-%?djbVt$&OHLHcN;QsKDx@zIby8}31@rA$*=6~9UK#kn z02{y+i*o}+3S&j75hhB_oIi0Q?(oUzp`LP|8IJ>^;ar!T6_cDM8?2_ ztCNMnAt7&;^wigfu&({Tz_$8IC3@PiW8k#q@9Vf^;71)Y6KH{kl^^Crx=Sr6Aw|5=d>6<;5I^zs5jAe21pfw z-?F|cq3yIA$l1m(Y9~k?Rw@86{(1bb!-vVj2@8<+nqJ2YI}wxfttpW&UZo~!-=>44 z1bHn%ClJlmrtllGeBpXe6#!^@M|g=lOtLwBI>-mSUz%9HzL3TijIvC;u?Rlvu4)Gaw{Ee#f4xN&M7J4^VO-^=6M<7MYS^hiiazzS_ zE|bE6HKF)zJpkL6j94Ux;P>N(uZdC*jDBZNTQ@SEbfROvnogsAB>?MIvf3+$G1ErkeAtmS(i*$IvdP$>7EZIxpMAOsLCGZ zhmrogoG8TZ<@(?ZBv8<7!6RetMk z9mFmB#KEXK`2K7qR-=igwWS*KeB(t>q|jAw)WVAX*LE?XL}OlM1L6OqE!eC6zChm9 zZ38mILP}s!xdFDm{T^h$?r+khKK;_X;8aS2p}NSXI94re*+T)C^QXY}U((@vh8q?> z3zO0iuop~nCko(Zs-&3>llbWeATKfC$X*=77O=GUNm1R+o!f2XB8TFKI#SYg8QgjL z=-_E4hA|Gi2?J#IS_~+V`6iuqO46t4-rS^vPvMnplH?&66&{B{plu3{ri-R6VM8iOUM4{wNM~bKY}syE=Ui(6@9YG z(pRaTj--YVZjX{bU%nVU>B2rZP74qd6A3}0$MP-e)n~-+Y{bQ=1>&=eT8FwHHT&=D zdjIkPQO#dq{#y0(z~0`+Ug9!f->RvurJT6BwKwt5Fv^_!O^vU$y&qr@5F5QHr}l36 z@34Z>QhVrZor=}8sqg|fY=Ye9M;gke)F}Y~9>dm*gFOKLsR{;}zSll;vg~`{@WMz? zXI=)JYd5!G^+1$A?t3~gbhk&I=ZQ>h~hh&bR zbh``p@`$0F3r5DB;}AZgXDBOkx6l3&+R0G865Fc|cu+Q;#n8~@KQ%yZ%RNTX6&=)s z+AS^s|8lwhBY#B}(|b;wd##iQXjckYOe~M1{Y$wg&#}sV6-40p0=x$#B=;~oUe?aB z1CyuA4n^!xt?uAU{C9GGTr_TE7M?4hqhR~k5)_WTisA&>4XEunimnDt%#@=(=UZIt z|Ha)PZ}Xgdn50{$N-GSHitnJM8~hDB8NGWrA8F3DSaR|9+q<|;gE1fxM`P_PAK(;` zS$y+;D5g4A3*Xp7+Zs{T@doAI$rMEK#qKoizLpTNz}* z7MmAxZlgmJ9|-U~Td)M8B8`BQsAtc)cRC#eL#}J}#E)w>b7$^fM@=4~9@q<`FIj8( z41=XJkME*RZOdw$U(3D)_A%GK1=#xr4gH6%dE4FXT~@UfVbuS{%Nri7<2|ZjE%pp^ z@3vWx(gov}j2o;eHFyW*PmSYWPrq7L-4$;0_=ra*#|9|zt6W?Wkin^D^VE%=74$;Q z1=4)h%Xa?SEL#dM*tzOM1)~1#sxq!YVyCevH}i&KXW-zX@LTOeb7r2vrLAq<{h^+K z`J>0VYH#R7Pwt0Q8U#lo!$s|Mh9Vl8AFaHjjJfq;J3i7qO6fO3-_nEPU~9(`SnO}h zsrPK<*;uhZM$P3Jz2a;s3n!v(Fx04)Qs@;0bN-@`6Bs9xIlQFFHPy8Y)iH668p|z3gKN$|tiM zX`}M`t=>oVM~OPR!nQK+*8GLd65{^E92I~iZhraw)taTS?9|n8sNF4sbDf!Md#jbg zXBn^-QmcCtgT=<)&Oz(}S>r0RF(fbr&7&r=**>X1ii+rORiIXvYSA-!qfLVPgksiZ z`xJf*r_!B0tWpb>#(GiRY@(7616FsFfB@j!#V$X$al64Xv7rr6^dbG{w8c-b>n)G; zeqb+Jq!eQ-Z^Oz1oOS5}L#u;MrMqE!wRw_-9rnL|N4_XgRiHDjppeOl~RV%v2d z`cvbS7t1q#HC?R-Kt(sIWKcqu|2~_o)f4+?3r6BwpFroc61i4%XV*}|^EJ>izt)H& zawzmPxk#%$QgEmIUJy~zEJDYOF(iMxyv6B0&0}ms>wTifq8`NAF8rDg^}~Uv^vkYLiaNW-i)`?`Y+uU=5)?-!^%(Ku@MR z1sp#mf-9BOBzZxIP8dP+3~EUlTbmoCSL4#G^iZ^3gRxU5Bc>3{(1Qxmi?b_FU8~oM z?5-9ccM8WG8b>Cda2SyqzmfL_n%QmZZ?rO9QacNLF`wup1Gm({{i4-%Adv9Kg!cNy z3hP$_`8&nF??#Cd$ox_GWok2)uAFffrR%VwYtAarRwCAIJy4Pdv>o^CeNu}BNB5|? zQIy=47=+0HHGpfiis$zzgH@AvZni+?^YLO}M~FYsO*E?3^a^TW^Es)-5)A1gKxaL_ z3x?2o(S|($giPAzflHi>awI?ydldybKZL{N;x#4$l8gO&A;E!FA}(Pydvdu zmX4WZ={A{Vt+Fo^;%MkaA>6D0tDO$aYX=F@ip z!I%D3tfsn4Z77?#&X|HC=7X8>n{S+DO3C}Aw#Y11OqUKrN&cuVqF5!fcNyl?7M(3~ zs)syRO23#I!p(q}L_5Db-+DE*_aTN=YH>EJ(vE^9d(_g^%HbRcW;4s3+1$c-PRDgixp*-H z^TWG=FBH!P3#XEB{ej2IKsX2aJW?Uc9qd*Fin^}yqHk(BKdY{UHm-FGR>e%GhEx8) zs{Xh##&Zy;4#0%~%9=@sy$@b>NU#zv+%{7bt#$LYnHsL8xO8lkru;m3gugNQ2P4Gp z=}IrxS5O#}9?Jh8U5%_KBH8B=V?Tdpl(BNT{JRprI&bwJ+-p%$>Gw<=rL)Zo!t}tU z8UC5gBvVb&I3T>KVw#Ftly_iE_M~m^((^91_)6Jckb_S^w*k{;C_97_zGQuh>s!x} zASHju)B3iV#T;HmT=~1421S6ukvtP61j19MM$YVXBo)50TGTXbf1x|QnPuk3wO>r~ z2nejQT?f)oQlaJGPV2VS97{fbM9^AfNr@AjIvqrrl3~hUnI0R1!(L0VmhzRGHGbX` z+d1NFdRX?wSW6v&iMAHhhya8tm+cAUKfcj~h;3U7vCEh20~c7|8lplMGyn;LT4!?7 zy-=h+5jWT3M?B^*=5#MaQ!ZfCbo~T~PT(g~3_OhxO4@suNVQ*!m4l3P)xAw#Cw--~D=WFc4CLkSzK8XSx)Y zE@`f%GYGSSMKh-DIem*!!V6(ttRfdI9QVs-s;;vX^4EANMSK>q92`etPs!3JWg;)i z_WSNT8lUyrC*d5I`{bun-?aQi8HkruNkRW0Y~=2k5P{`vXFH)1TXn z7xQ2JJ(n*V<8&y@jjND2(e525{F<3EUB86rh{Gh!P!U+6L`wDfIEzg2lg~ zo?Zte5e>Juzuy}Y+>o5iL&DYT;x_7;#P(s+7e%`!n`!vHP^d0z3|2uEr>C&D=msEW+!;ZZgiC(Q@a*CjNO5IJ%y}-W{kjW)8!!iS>nEwJ# C2`@1K literal 8155 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 diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl index bb283f245ba..bdb31c67be5 100644 --- a/nano/templates/appearance_changer.tmpl +++ b/nano/templates/appearance_changer.tmpl @@ -35,7 +35,10 @@ {{if data.change_skin_tone}} {{:helper.link('Change skin tone', null, { 'skin_tone' : 1})}} {{/if}} - {{if data.change_skin_color}} + {{if data.change_skin_preset}} + {{:helper.link('Change skin preset', null, { 'skin_preset' : 1})}} + {{/if}} + {{if data.change_skin_color && !data.change_skin_preset}} {{:helper.link('Change skin color', null, { 'skin_color' : 1})}} {{/if}} {{if data.change_hair_color}}