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 aafc841e2b5..e18ce310a18 100644 Binary files a/icons/mob/body_accessory.dmi and b/icons/mob/body_accessory.dmi differ