From 0f8f514671d89735a22b0824a41d831133de5f84 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Mon, 21 Dec 2015 22:55:39 -0500 Subject: [PATCH] Adds Unathi Horn and Tail Customization Does not include tail colour correction. In this iteration, the horns do not have their own colour-- they use the skin colour. --- code/__HELPERS/global_lists.dm | 2 + code/_globalvars/lists/flavor_misc.dm | 2 + code/datums/datacore.dm | 10 +++ code/modules/client/preferences.dm | 20 ++++++ code/modules/client/preferences_savefile.dm | 2 + .../living/carbon/human/body_accessories.dm | 2 + .../mob/living/carbon/human/human_defines.dm | 4 ++ .../mob/living/carbon/human/update_icons.dm | 58 +++++++++++++++--- .../mob/new_player/preferences_setup.dm | 7 +++ .../mob/new_player/sprite_accessories.dm | 52 +++++++++++++++- icons/mob/body_accessory.dmi | Bin 9705 -> 10072 bytes 11 files changed, 148 insertions(+), 11 deletions(-) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 500553e1f28..185d02d69d6 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -4,6 +4,8 @@ ////////////////////////// /proc/makeDatumRefLists() + //horns + init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, horn_styles_list) //hair init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, hair_styles_list, hair_styles_male_list, hair_styles_female_list) //facial hair diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 516ae5630f9..4887c4d12f7 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -1,4 +1,6 @@ //Preferences stuff + //Hornstyles +var/global/list/horn_styles_list = list() //stores /datum/sprite_accessory/horns indexed by name //Hairstyles var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name var/global/list/hair_styles_male_list = list() diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 7f0e58d3bbb..0dd408a0028 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -179,6 +179,16 @@ proc/get_id_photo(var/mob/living/carbon/human/H) facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) eyes_s.Blend(facial_s, ICON_OVERLAY) + //Horns + if(H.species && H.species.name == "Unathi") + var/datum/sprite_accessory/horns = horn_styles_list[H.horns] + if(horns) + var/icon/horns_s = new/icon("icon" = horns.icon, "icon_state" = "[horns.icon_state]_s") + horns_s.Blend(rgb(H.r_skin, H.g_skin, H.b_skin), ICON_ADD) + eyes_s.Blend(horns_s, ICON_OVERLAY) + + preview_icon.Blend(eyes_s, ICON_OVERLAY) + var/icon/clothes_s = null switch(H.mind.assigned_role) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index e7987280d48..f907ca9837d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -111,6 +111,7 @@ datum/preferences var/socks = "Nude" //socks type var/backbag = 2 //backpack type var/h_style = "Bald" //Hair type + var/horns = "None" //Horn style var/r_hair = 0 //Hair color var/g_hair = 0 //Hair color var/b_hair = 0 //Hair color @@ -353,6 +354,10 @@ datum/preferences dat += "[TextPreview(flavor_text)]...
" dat += "
" + if(species == "Unathi") + dat += "
Horns
" + dat += "Style: [horns]
" + var/hairname = "Hair" if(species == "Machine") hairname = "Frame Color" @@ -1188,6 +1193,19 @@ datum/preferences if(new_h_style) h_style = new_h_style + if("horns") + var/list/valid_hornstyles = list() + for(var/hornstyle in horn_styles_list) + var/datum/sprite_accessory/H = horn_styles_list[hornstyle] + if( !(species in H.species_allowed)) + continue + + valid_hornstyles[hornstyle] = horn_styles_list[hornstyle] + + var/new_horn_style = input(user, "Choose your character's horn style:", "Character Preference") as null|anything in valid_hornstyles + if(new_horn_style) + horns = new_horn_style + if("body_accessory") var/list/possible_body_accessories = list() if(check_rights(R_ADMIN, 1, user)) @@ -1607,6 +1625,8 @@ datum/preferences character.undershirt = undershirt character.socks = socks + if(character.species.name == "Unathi") + character.horns = horns if(body_accessory) character.body_accessory = body_accessory_by_name["[body_accessory]"] diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index f1dd7b307f3..8d74bbb3cbd 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -134,6 +134,7 @@ S["skin_red"] >> r_skin S["skin_green"] >> g_skin S["skin_blue"] >> b_skin + S["horn_style_name"] >> horns S["hair_style_name"] >> h_style S["facial_style_name"] >> f_style S["eyes_red"] >> r_eyes @@ -197,6 +198,7 @@ r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin)) g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin)) b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin)) + horns = sanitize_inlist(horns, horn_styles_list, initial(horns)) h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style)) f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style)) r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes)) diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index 452317e7c4b..f9450c457ee 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -91,6 +91,8 @@ var/global/list/body_accessory_by_species = list("None" = null) icon = 'icons/mob/body_accessory.dmi' animated_icon = 'icons/mob/body_accessory.dmi' blend_mode = ICON_ADD + icon_state = "null" + animated_icon_state = "null" /datum/body_accessory/tail/try_restrictions(var/mob/living/carbon/human/H) if(!H.wear_suit || !(H.wear_suit.flags_inv & HIDETAIL) && !istype(H.wear_suit, /obj/item/clothing/suit/space)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 0bc919e4b0c..f2592a653c3 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,12 +1,16 @@ /mob/living/carbon/human hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD) + //Hair colour and style var/r_hair = 0 var/g_hair = 0 var/b_hair = 0 var/h_style = "Bald" + //Horns + var/horns = "None" + //Facial hair colour and style var/r_facial = 0 var/g_facial = 0 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index d21aea4bde2..16ec5ace8ad 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -120,16 +120,17 @@ Please contact me on #coderbus IRC. ~Carn x #define SUIT_STORE_LAYER 13 #define BACK_LAYER 14 #define HAIR_LAYER 15 //TODO: make part of head layer? -#define FACEMASK_LAYER 16 -#define HEAD_LAYER 17 -#define COLLAR_LAYER 18 -#define HANDCUFF_LAYER 19 -#define LEGCUFF_LAYER 20 -#define L_HAND_LAYER 21 -#define R_HAND_LAYER 22 -#define TARGETED_LAYER 23 //BS12: Layer for the target overlay from weapon targeting system -#define FIRE_LAYER 24 //If you're on fire -#define TOTAL_LAYERS 24 +#define HORN_LAYER 16 +#define FACEMASK_LAYER 17 +#define HEAD_LAYER 18 +#define COLLAR_LAYER 19 +#define HANDCUFF_LAYER 20 +#define LEGCUFF_LAYER 21 +#define L_HAND_LAYER 22 +#define R_HAND_LAYER 23 +#define TARGETED_LAYER 24 //BS12: Layer for the target overlay from weapon targeting system +#define FIRE_LAYER 25 //If you're on fire +#define TOTAL_LAYERS 25 @@ -350,6 +351,42 @@ var/global/list/damage_icon_parts = list() //tail update_tail_layer(0) + //horns + update_horns(0) + + +//HORN OVERLAY +/mob/living/carbon/human/proc/update_horns(var/update_icons=1) + //Reset our horns + overlays_standing[HORN_LAYER] = null + + var/obj/item/organ/external/head/head_organ = get_organ("head") + if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED) ) + if(update_icons) update_icons() + return + + //masks and helmets can obscure our horns, unless we're a synthetic + if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR))) + if(update_icons) update_icons() + return + + //base icons + var/icon/horns_standing = new /icon('icons/mob/body_accessory.dmi',"horns_none_s") + + if(horns && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()) && (src.species.name == "Unathi"))) + var/datum/sprite_accessory/horn_style = horn_styles_list[horns] + if(horn_style && horn_style.species_allowed) + if(src.species.name in horn_style.species_allowed) + var/icon/horns_s = new/icon("icon" = horn_style.icon, "icon_state" = "[horn_style.icon_state]_s") + if(horn_style.do_colouration) + horns_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + horns_standing.Blend(horns_s, ICON_OVERLAY) + else + //warning("Invalid horns for [species.name]: [horns]") + + overlays_standing[HORN_LAYER] = image(horns_standing) + + if(update_icons) update_icons() //HAIR OVERLAY @@ -1032,6 +1069,7 @@ var/global/list/damage_icon_parts = list() #undef BACK_LAYER #undef HAIR_LAYER #undef HEAD_LAYER +#undef HORN_LAYER #undef COLLAR_LAYER #undef HANDCUFF_LAYER #undef LEGCUFF_LAYER diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index f1b9b80e9ab..30b9db678a7 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -263,6 +263,13 @@ datum/preferences facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) eyes_s.Blend(facial_s, ICON_OVERLAY) + //Horns + if(current_species && current_species.name == "Unathi") + var/datum/sprite_accessory/horn_style = horn_styles_list[horns] + if(horn_style) + var/icon/horns_s = new/icon("icon" = horn_style.icon, "icon_state" = "[horn_style.icon_state]_s") + horns_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + eyes_s.Blend(horns_s, ICON_OVERLAY) var/icon/underwear_s = null if(underwear && current_species.clothing_flags & HAS_UNDERWEAR) diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 50183e4e506..b857c6c6adb 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -1498,4 +1498,54 @@ name = "Vox Fishnets" icon_state = "vox_fishnet" gender = NEUTER - species_allowed = list("Vox") \ No newline at end of file + species_allowed = list("Vox") + +/* HORNS */ + +/datum/sprite_accessory/horns + icon = 'icons/mob/body_accessory.dmi' + species_allowed = list("Unathi") + icon_state = null + +/datum/sprite_accessory/horns/none + name = "None" + icon_state = "horns_none" + +/datum/sprite_accessory/horns/simple + name = "Simple" + icon_state = "horns_simple" + +/datum/sprite_accessory/horns/short + name = "Short" + icon_state = "horns_short" + +/datum/sprite_accessory/horns/curled + name = "Curled" + icon_state = "horns_curled" + +/datum/sprite_accessory/horns/ram + name = "Ram" + icon_state = "horns_ram" + +/* FRILLS */ + +/datum/sprite_accessory/frills + icon = 'icons/mob/body_accessory.dmi' + species_allowed = list("Unathi") + icon_state = null + +/datum/sprite_accessory/frills/none + name = "None" + icon_state = null + +/datum/sprite_accessory/frills/simple + name = "Simple" + icon_state = "simple" + +/datum/sprite_accessory/frills/short + name = "Short" + icon_state = "short" + +/datum/sprite_accessory/frills/aquatic + name = "Aquatic" + icon_state = "aqua" diff --git a/icons/mob/body_accessory.dmi b/icons/mob/body_accessory.dmi index aafc841e2b54b49c5ff11c4b40b137edcc54992b..e18ce310a18f3f4a470f48e10b7d22e1afa9bd74 100644 GIT binary patch literal 10072 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 G)&BzXYAu@p literal 9705 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