From f95655419c410307b7593a9b76c9c985075dd801 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Sat, 30 Apr 2016 08:12:41 -0400 Subject: [PATCH 01/10] Refactors Hair so it's on the Head + Adds a Vox Hairstyle + Adjusts Vox Hairstyle Names for Consistency -- PASS 1 Also fixes a typo or two. TO DO: FULLY TEST AND SWEEP FOR BUGS, ERRORS AND RUNTIMES --- code/datums/datacore.dm | 19 +++--- .../datums/diseases/advance/symptoms/beard.dm | 13 ++-- .../diseases/advance/symptoms/shedding.dm | 11 ++-- code/game/dna/dna2.dm | 37 ++++++----- code/game/dna/dna2_helpers.dm | 25 +++---- code/game/dna/genes/vg_powers.dm | 25 +++---- code/game/gamemodes/blob/blobs/blob_mobs.dm | 3 +- code/game/gamemodes/heist/heist.dm | 5 +- code/game/gamemodes/nuclear/nuclear.dm | 18 ++--- code/game/objects/items/weapons/cosmetics.dm | 18 ++--- code/game/objects/items/weapons/scissors.dm | 22 +++---- code/game/response_team.dm | 17 ++--- code/modules/admin/verbs/one_click_antag.dm | 5 +- code/modules/client/preferences.dm | 31 +++++---- code/modules/clothing/head/misc_special.dm | 7 +- .../mob/living/carbon/human/appearance.dm | 62 ++++++++++-------- code/modules/mob/living/carbon/human/death.dm | 18 ++--- code/modules/mob/living/carbon/human/human.dm | 56 ++++++++++------ .../mob/living/carbon/human/human_defines.dm | 18 ----- .../mob/living/carbon/human/species/apollo.dm | 5 +- .../living/carbon/human/species/station.dm | 4 +- .../mob/living/carbon/human/update_icons.dm | 43 ++++++------ code/modules/mob/living/carbon/superheroes.dm | 5 +- .../mob/new_player/sprite_accessories.dm | 9 ++- code/modules/nano/modules/human_appearance.dm | 10 +-- code/modules/reagents/newchem/other.dm | 23 ++++--- code/modules/surgery/limb_reattach.dm | 6 +- code/modules/surgery/organs/organ_icon.dm | 29 ++++---- code/modules/surgery/organs/organ_internal.dm | 23 +++---- .../surgery/organs/subtypes/standard.dm | 18 +++++ icons/mob/human_face.dmi | Bin 71587 -> 71902 bytes 31 files changed, 322 insertions(+), 263 deletions(-) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index a70875a7090..d07b6e3eb73 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -126,6 +126,7 @@ proc/get_id_photo(var/mob/living/carbon/human/H) var/icon/preview_icon = null + var/obj/item/organ/external/head/head_organ = H.get_organ("head") var/g = "m" if (H.gender == FEMALE) @@ -170,32 +171,32 @@ proc/get_id_photo(var/mob/living/carbon/human/H) eyes_s.Blend(rgb(H.r_eyes, H.g_eyes, H.b_eyes), ICON_ADD) face_s.Blend(eyes_s, ICON_OVERLAY) - var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] + var/datum/sprite_accessory/hair_style = hair_styles_list[head_organ.h_style] if(hair_style) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") // I'll want to make a species-specific proc for this sooner or later // But this'll do for now - if(H.get_species() == "Slime People") + if(head_organ.species.name == "Slime People") hair_s.Blend(rgb(H.r_skin, H.g_skin, H.b_skin, 160), ICON_ADD) else - hair_s.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) + hair_s.Blend(rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair), ICON_ADD) face_s.Blend(hair_s, ICON_OVERLAY) //Head Accessory - if(H.species.bodyflags & HAS_HEAD_ACCESSORY) - var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[H.ha_style] + if(head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[head_organ.ha_style] if(head_accessory_style && head_accessory_style.species_allowed) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") - head_accessory_s.Blend(rgb(H.r_headacc, H.g_headacc, H.b_headacc), ICON_ADD) + head_accessory_s.Blend(rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc), ICON_ADD) face_s.Blend(head_accessory_s, ICON_OVERLAY) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[head_organ.f_style] if(facial_hair_style && 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(H.get_species() == "Slime People") + if(head_organ.species.name == "Slime People") facial_s.Blend(rgb(H.r_skin, H.g_skin, H.b_skin, 160), ICON_ADD) else - facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) + facial_s.Blend(rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial), ICON_ADD) face_s.Blend(facial_s, ICON_OVERLAY) //Markings diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm index 1dda9b46f7f..b773d25cf9a 100644 --- a/code/datums/diseases/advance/symptoms/beard.dm +++ b/code/datums/diseases/advance/symptoms/beard.dm @@ -30,20 +30,21 @@ BONUS var/mob/living/M = A.affected_mob if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M + var/obj/item/organ/external/head/head_organ = H.get_organ("head") switch(A.stage) if(1, 2) to_chat(H, "Your chin itches.") - if(H.f_style == "Shaved") - H.f_style = "Jensen Beard" + if(head_organ.f_style == "Shaved") + head_organ.f_style = "Jensen Beard" H.update_hair() if(3, 4) to_chat(H, "You feel tough.") - if(!(H.f_style == "Dwarf Beard") && !(H.f_style == "Very Long Beard") && !(H.f_style == "Full Beard")) - H.f_style = "Full Beard" + if(!(head_organ.f_style == "Dwarf Beard") && !(head_organ.f_style == "Very Long Beard") && !(head_organ.f_style == "Full Beard")) + head_organ.f_style = "Full Beard" H.update_hair() else to_chat(H, "You feel manly!") - if(!(H.f_style == "Dwarf Beard") && !(H.f_style == "Very Long Beard")) - H.f_style = pick("Dwarf Beard", "Very Long Beard") + if(!(head_organ.f_style == "Dwarf Beard") && !(head_organ.f_style == "Very Long Beard")) + head_organ.f_style = pick("Dwarf Beard", "Very Long Beard") H.update_hair() return \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm index f7f52984c0b..dd1fc5183a6 100644 --- a/code/datums/diseases/advance/symptoms/shedding.dm +++ b/code/datums/diseases/advance/symptoms/shedding.dm @@ -31,18 +31,19 @@ BONUS to_chat(M, "[pick("Your scalp itches.", "Your skin feels flakey.")]") if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M + var/obj/item/organ/external/head/head_organ = H.get_organ("head") switch(A.stage) if(3, 4) - if(!(H.h_style == "Bald") && !(H.h_style == "Balding Hair")) + if(!(head_organ.h_style == "Bald") && !(head_organ.h_style == "Balding Hair")) to_chat(H, "Your hair starts to fall out in clumps...") spawn(50) - H.h_style = "Balding Hair" + head_organ.h_style = "Balding Hair" H.update_hair() if(5) - if(!(H.f_style == "Shaved") || !(H.h_style == "Bald")) + if(!(head_organ.f_style == "Shaved") || !(head_organ.h_style == "Bald")) to_chat(H, "Your hair starts to fall out in clumps...") spawn(50) - H.f_style = "Shaved" - H.h_style = "Bald" + head_organ.f_style = "Shaved" + head_organ.h_style = "Bald" H.update_hair() return \ No newline at end of file diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index a15170a3956..93d7cc473dc 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -133,19 +133,20 @@ var/global/list/bad_blocks[0] ResetUI(1) // Hair // FIXME: Species-specific defaults pls - if(!character.h_style) - character.h_style = "Skinhead" - var/hair = hair_styles_list.Find(character.h_style) + var/obj/item/organ/external/head/H = character.get_organ("head") + if(!H.h_style) + H.h_style = "Skinhead" + var/hair = hair_styles_list.Find(H.h_style) // Facial Hair - if(!character.f_style) - character.f_style = "Shaved" - var/beard = facial_hair_styles_list.Find(character.f_style) + if(!H.f_style) + H.f_style = "Shaved" + var/beard = facial_hair_styles_list.Find(H.f_style) // Head Accessory - if(!character.ha_style) - character.ha_style = "None" - var/headacc = head_accessory_styles_list.Find(character.ha_style) + if(!H.ha_style) + H.ha_style = "None" + var/headacc = head_accessory_styles_list.Find(H.ha_style) /*// Body Accessory if(!character.body_accessory) @@ -157,13 +158,13 @@ var/global/list/bad_blocks[0] character.m_style = "None" var/marks = marking_styles_list.Find(character.m_style) - SetUIValueRange(DNA_UI_HAIR_R, character.r_hair, 255, 1) - SetUIValueRange(DNA_UI_HAIR_G, character.g_hair, 255, 1) - SetUIValueRange(DNA_UI_HAIR_B, character.b_hair, 255, 1) + SetUIValueRange(DNA_UI_HAIR_R, H.r_hair, 255, 1) + SetUIValueRange(DNA_UI_HAIR_G, H.g_hair, 255, 1) + SetUIValueRange(DNA_UI_HAIR_B, H.b_hair, 255, 1) - SetUIValueRange(DNA_UI_BEARD_R, character.r_facial, 255, 1) - SetUIValueRange(DNA_UI_BEARD_G, character.g_facial, 255, 1) - SetUIValueRange(DNA_UI_BEARD_B, character.b_facial, 255, 1) + SetUIValueRange(DNA_UI_BEARD_R, H.r_facial, 255, 1) + SetUIValueRange(DNA_UI_BEARD_G, H.g_facial, 255, 1) + SetUIValueRange(DNA_UI_BEARD_B, H.b_facial, 255, 1) SetUIValueRange(DNA_UI_EYES_R, character.r_eyes, 255, 1) SetUIValueRange(DNA_UI_EYES_G, character.g_eyes, 255, 1) @@ -173,9 +174,9 @@ var/global/list/bad_blocks[0] SetUIValueRange(DNA_UI_SKIN_G, character.g_skin, 255, 1) SetUIValueRange(DNA_UI_SKIN_B, character.b_skin, 255, 1) - SetUIValueRange(DNA_UI_HACC_R, character.r_headacc, 255, 1) - SetUIValueRange(DNA_UI_HACC_G, character.g_headacc, 255, 1) - SetUIValueRange(DNA_UI_HACC_B, character.b_headacc, 255, 1) + SetUIValueRange(DNA_UI_HACC_R, H.r_headacc, 255, 1) + SetUIValueRange(DNA_UI_HACC_G, H.g_headacc, 255, 1) + SetUIValueRange(DNA_UI_HACC_B, H.b_headacc, 255, 1) SetUIValueRange(DNA_UI_MARK_R, character.r_markings, 255, 1) SetUIValueRange(DNA_UI_MARK_G, character.g_markings, 255, 1) diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 781c3a1d230..53f248d1e91 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -131,13 +131,14 @@ src.dna.UpdateUI() dna.check_integrity() var/mob/living/carbon/human/H = src - H.r_hair = dna.GetUIValueRange(DNA_UI_HAIR_R, 255) - H.g_hair = dna.GetUIValueRange(DNA_UI_HAIR_G, 255) - H.b_hair = dna.GetUIValueRange(DNA_UI_HAIR_B, 255) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + head_organ.r_hair = dna.GetUIValueRange(DNA_UI_HAIR_R, 255) + head_organ.g_hair = dna.GetUIValueRange(DNA_UI_HAIR_G, 255) + head_organ.b_hair = dna.GetUIValueRange(DNA_UI_HAIR_B, 255) - H.r_facial = dna.GetUIValueRange(DNA_UI_BEARD_R, 255) - H.g_facial = dna.GetUIValueRange(DNA_UI_BEARD_G, 255) - H.b_facial = dna.GetUIValueRange(DNA_UI_BEARD_B, 255) + head_organ.r_facial = dna.GetUIValueRange(DNA_UI_BEARD_R, 255) + head_organ.g_facial = dna.GetUIValueRange(DNA_UI_BEARD_G, 255) + head_organ.b_facial = dna.GetUIValueRange(DNA_UI_BEARD_B, 255) H.r_skin = dna.GetUIValueRange(DNA_UI_SKIN_R, 255) H.g_skin = dna.GetUIValueRange(DNA_UI_SKIN_G, 255) @@ -147,9 +148,9 @@ H.g_eyes = dna.GetUIValueRange(DNA_UI_EYES_G, 255) H.b_eyes = dna.GetUIValueRange(DNA_UI_EYES_B, 255) - H.r_headacc = dna.GetUIValueRange(DNA_UI_HACC_R, 255) - H.g_headacc = dna.GetUIValueRange(DNA_UI_HACC_G, 255) - H.b_headacc = dna.GetUIValueRange(DNA_UI_HACC_B, 255) + head_organ.r_headacc = dna.GetUIValueRange(DNA_UI_HACC_R, 255) + head_organ.g_headacc = dna.GetUIValueRange(DNA_UI_HACC_G, 255) + head_organ.b_headacc = dna.GetUIValueRange(DNA_UI_HACC_B, 255) H.r_markings = dna.GetUIValueRange(DNA_UI_MARK_R, 255) H.g_markings = dna.GetUIValueRange(DNA_UI_MARK_G, 255) @@ -168,17 +169,17 @@ //Hair var/hair = dna.GetUIValueRange(DNA_UI_HAIR_STYLE,hair_styles_list.len) if((0 < hair) && (hair <= hair_styles_list.len)) - H.h_style = hair_styles_list[hair] + head_organ.h_style = hair_styles_list[hair] //Facial Hair var/beard = dna.GetUIValueRange(DNA_UI_BEARD_STYLE,facial_hair_styles_list.len) if((0 < beard) && (beard <= facial_hair_styles_list.len)) - H.f_style = facial_hair_styles_list[beard] + head_organ.f_style = facial_hair_styles_list[beard] //Head Accessories var/headacc = dna.GetUIValueRange(DNA_UI_HACC_STYLE,head_accessory_styles_list.len) if((0 < headacc) && (headacc <= head_accessory_styles_list.len)) - H.ha_style = head_accessory_styles_list[headacc] + head_organ.ha_style = head_accessory_styles_list[headacc] //Markings var/marks = dna.GetUIValueRange(DNA_UI_MARK_STYLE,marking_styles_list.len) diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index 8a854c7980d..5511642e53e 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -37,18 +37,19 @@ to_chat(usr, "\red You can't change your appearance right now!") return var/mob/living/carbon/human/M=usr + var/obj/item/organ/external/head/head_organ = M.get_organ("head") - var/new_facial = input("Please select facial hair color.", "Character Generation",rgb(M.r_facial,M.g_facial,M.b_facial)) as null|color + var/new_facial = input("Please select facial hair color.", "Character Generation",rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial)) as null|color if(new_facial) - M.r_facial = hex2num(copytext(new_facial, 2, 4)) - M.g_facial = hex2num(copytext(new_facial, 4, 6)) - M.b_facial = hex2num(copytext(new_facial, 6, 8)) + head_organ.r_facial = hex2num(copytext(new_facial, 2, 4)) + head_organ.g_facial = hex2num(copytext(new_facial, 4, 6)) + head_organ.b_facial = hex2num(copytext(new_facial, 6, 8)) - var/new_hair = input("Please select hair color.", "Character Generation",rgb(M.r_hair,M.g_hair,M.b_hair)) as null|color + var/new_hair = input("Please select hair color.", "Character Generation",rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair)) as null|color if(new_facial) - M.r_hair = hex2num(copytext(new_hair, 2, 4)) - M.g_hair = hex2num(copytext(new_hair, 4, 6)) - M.b_hair = hex2num(copytext(new_hair, 6, 8)) + head_organ.r_hair = hex2num(copytext(new_hair, 2, 4)) + head_organ.g_hair = hex2num(copytext(new_hair, 4, 6)) + head_organ.b_hair = hex2num(copytext(new_hair, 6, 8)) var/new_eyes = input("Please select eye color.", "Character Generation",rgb(M.r_eyes,M.g_eyes,M.b_eyes)) as null|color if(new_eyes) @@ -73,11 +74,11 @@ hairs.Add(H.name) // add hair name to hairs qdel(H) // delete the hair after it's all done - var/new_style = input("Please select hair style", "Character Generation",M.h_style) as null|anything in hairs + var/new_style = input("Please select hair style", "Character Generation", head_organ.h_style) as null|anything in hairs // if new style selected (not cancel) if (new_style) - M.h_style = new_style + head_organ.h_style = new_style // facial hair var/list/all_fhairs = subtypesof(/datum/sprite_accessory/facial_hair) @@ -88,10 +89,10 @@ fhairs.Add(H.name) qdel(H) - new_style = input("Please select facial style", "Character Generation",M.f_style) as null|anything in fhairs + new_style = input("Please select facial style", "Character Generation", head_organ.f_style) as null|anything in fhairs if(new_style) - M.f_style = new_style + head_organ.f_style = new_style var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") if (new_gender) diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index a35505470fa..229b35660a3 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -68,6 +68,7 @@ ..() /mob/living/simple_animal/hostile/blob/blobspore/proc/Zombify(var/mob/living/carbon/human/H) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") is_zombie = 1 if(H.wear_suit) var/obj/item/clothing/suit/armor/A = H.wear_suit @@ -82,7 +83,7 @@ icon = H.icon speak_emote = list("groans") icon_state = "zombie2_s" - H.h_style = null + head_organ.h_style = null H.update_hair() human_overlays = H.overlays update_icons() diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 057c43345f8..85244067c54 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -95,6 +95,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah")) var/mob/living/carbon/human/vox = newraider.current + var/obj/item/organ/external/head/head_organ = vox.get_organ("head") vox.real_name = capitalize(newname) vox.name = vox.real_name @@ -106,8 +107,8 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' vox.add_language("Vox-pidgin") vox.add_language("Galactic Common") vox.add_language("Tradeband") - vox.h_style = "Short Vox Quills" - vox.f_style = "Shaved" + head_organ.h_style = "Short Vox Quills" + head_organ.f_style = "Shaved" for(var/obj/item/organ/external/limb in vox.organs) limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index f2d05507da1..3ba413027e1 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -134,6 +134,8 @@ proc/issyndicate(mob/living/M as mob) /datum/game_mode/proc/create_syndicate(var/datum/mind/synd_mind) // So we don't have inferior species as ops - randomize a human var/mob/living/carbon/human/M = synd_mind.current + var/obj/item/organ/external/head/head_organ = M.get_organ("head") + M.set_species("Human",1) M.dna.ready_dna(M) // Quadriplegic Nuke Ops won't be participating in the paralympics @@ -150,18 +152,18 @@ proc/issyndicate(mob/living/M as mob) if(prob(5)) facial_hair_style = pick(facial_hair_styles_list) - M.r_facial = hex2num(copytext(hair_c, 2, 4)) - M.g_facial = hex2num(copytext(hair_c, 4, 6)) - M.b_facial = hex2num(copytext(hair_c, 6, 8)) - M.r_hair = hex2num(copytext(hair_c, 2, 4)) - M.g_hair = hex2num(copytext(hair_c, 4, 6)) - M.b_hair = hex2num(copytext(hair_c, 6, 8)) + head_organ.r_facial = hex2num(copytext(hair_c, 2, 4)) + head_organ.g_facial = hex2num(copytext(hair_c, 4, 6)) + head_organ.b_facial = hex2num(copytext(hair_c, 6, 8)) + head_organ.r_hair = hex2num(copytext(hair_c, 2, 4)) + head_organ.g_hair = hex2num(copytext(hair_c, 4, 6)) + head_organ.b_hair = hex2num(copytext(hair_c, 6, 8)) M.r_eyes = hex2num(copytext(eye_c, 2, 4)) M.g_eyes = hex2num(copytext(eye_c, 4, 6)) M.b_eyes = hex2num(copytext(eye_c, 6, 8)) M.s_tone = skin_tone - M.h_style = hair_style - M.f_style = facial_hair_style + head_organ.h_style = hair_style + head_organ.f_style = facial_hair_style M.body_accessory = null /datum/game_mode/proc/prepare_syndicate_leader(var/datum/mind/synd_mind, var/nuke_code) diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 3e2448fa8fe..89a8b52b8da 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -91,16 +91,16 @@ /obj/item/weapon/razor/attack(mob/living/carbon/M as mob, mob/user as mob) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/external/head/C = H.organs_by_name["head"] + var/obj/item/organ/external/head/C = H.get_organ("head") var/datum/robolimb/robohead = all_robolimbs[C.model] if(user.zone_sel.selecting == "mouth") if(!get_location_accessible(H, "mouth")) to_chat(user, "The mask is in the way.") return - if((H.species && H.species.flags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... + if((C.species && C.species.flags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... to_chat(user, "You find yourself disappointed at the appalling lack of facial hair.") return - if(H.f_style == "Shaved") + if(C.f_style == "Shaved") to_chat(user, "Already clean-shaven.") return if(H == user) //shaving yourself @@ -109,7 +109,7 @@ if(do_after(user, 50, target = H)) user.visible_message("[user] shaves his facial hair clean with the [src].", \ "You finish shaving with the [src]. Fast and clean!") - H.f_style = "Shaved" + C.f_style = "Shaved" H.update_fhair() playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1) else @@ -121,17 +121,17 @@ if(user_loc == user.loc && H_loc == H.loc) user.visible_message("[user] shaves off [H]'s facial hair with \the [src].", \ "You shave [H]'s facial hair clean off.") - H.f_style = "Shaved" + C.f_style = "Shaved" H.update_fhair() playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1) if(user.zone_sel.selecting == "head") if(!get_location_accessible(H, "head")) to_chat(user, "The headgear is in the way.") return - if((H.species && H.species.flags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... + if((C.species && C.species.flags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... to_chat(user, "You find yourself disappointed at the appalling lack of hair.") return - if(H.h_style == "Bald" || H.h_style == "Balding Hair" || H.h_style == "Skinhead") + if(C.h_style == "Bald" || C.h_style == "Balding Hair" || C.h_style == "Skinhead") to_chat(user, "There is not enough hair left to shave...") return if(H == user) //shaving yourself @@ -140,7 +140,7 @@ if(do_after(user, 50, target = H)) user.visible_message("[user] shaves his head with the [src].", \ "You finish shaving with the [src].") - H.h_style = "Skinhead" + C.h_style = "Skinhead" H.update_hair() playsound(src.loc, 'sound/items/Welder2.ogg', 40, 1) else @@ -152,7 +152,7 @@ if(user_loc == user.loc && H_loc == H.loc) user.visible_message("[user] shaves [H]'s head bald with \the [src]!", \ "You shave [H]'s head bald.") - H.h_style = "Skinhead" + C.h_style = "Skinhead" H.update_hair() playsound(src.loc, 'sound/items/Welder2.ogg', 40, 1) else diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm index a5e0081e723..343c3788bdc 100644 --- a/code/game/objects/items/weapons/scissors.dm +++ b/code/game/objects/items/weapons/scissors.dm @@ -30,21 +30,21 @@ //this is largely copypasted from there. //handle facial hair (if necessary) var/list/species_facial_hair = list() - var/obj/item/organ/external/head/C = H.organs_by_name["head"] + var/obj/item/organ/external/head/C = H.get_organ("head") var/datum/robolimb/robohead = all_robolimbs[C.model] if(H.gender == MALE || H.get_species() == "Vulpkanin") - if(H.species) + if(C.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) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human hair styles. - if(H.species.flags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. + if(C.species.name in tmp_facial.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human hair styles. + if(C.species.flags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. if(robohead.is_monitor) to_chat(user, "You are unable to find anything on [H]'s face worth cutting. How disappointing.") return continue //If the head DOES support human hair wigs, make sure they don't get monitor-oriented styles. species_facial_hair += i else - if(H.species.flags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. + if(C.species.flags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. if(!robohead.is_monitor) if("Human" in tmp_facial.species_allowed) species_facial_hair += i @@ -56,18 +56,18 @@ var/f_new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in species_facial_hair //handle normal hair var/list/species_hair = list() - if(H.species) + if(C.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) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human facial hair styles. - if(H.species.flags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. + if(C.species.name in tmp_hair.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human facial hair styles. + if(C.species.flags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. if(robohead.is_monitor) to_chat(user, "You are unable to find anything on [H]'s head worth cutting. How disappointing.") return continue //If the head DOES support human hair wigs, make sure they don't get monitor-oriented styles. species_hair += i else - if(H.species.flags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. + if(C.species.flags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. if(!robohead.is_monitor) if("Human" in tmp_hair.species_allowed) species_hair += i @@ -84,9 +84,9 @@ user.visible_message("[user] stops cutting [M]'s hair.", "You stop cutting [M]'s hair.") return if(f_new_style) - H.f_style = f_new_style + C.f_style = f_new_style if(h_new_style) - H.h_style = h_new_style + C.h_style = h_new_style H.update_hair() user.visible_message("[user] finishes cutting [M]'s hair!") diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 14bf44ff7b5..241e317c24b 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -148,6 +148,7 @@ var/send_emergency_team /client/proc/create_response_team(obj/spawn_location) var/mob/living/carbon/human/M = new(null) + var/obj/item/organ/external/head/head_organ = M.get_organ("head") response_team_members |= M var/new_gender = alert(usr, "Please select your gender.", "Character Generation", "Male", "Female") @@ -173,18 +174,18 @@ var/send_emergency_team if(prob(5)) facial_hair_style = pick(facial_hair_styles_list) - M.r_facial = hex2num(copytext(hair_c, 2, 4)) - M.g_facial = hex2num(copytext(hair_c, 4, 6)) - M.b_facial = hex2num(copytext(hair_c, 6, 8)) - M.r_hair = hex2num(copytext(hair_c, 2, 4)) - M.g_hair = hex2num(copytext(hair_c, 4, 6)) - M.b_hair = hex2num(copytext(hair_c, 6, 8)) + head_organ.r_facial = hex2num(copytext(hair_c, 2, 4)) + head_organ.g_facial = hex2num(copytext(hair_c, 4, 6)) + head_organ.b_facial = hex2num(copytext(hair_c, 6, 8)) + head_organ.r_hair = hex2num(copytext(hair_c, 2, 4)) + head_organ.g_hair = hex2num(copytext(hair_c, 4, 6)) + head_organ.b_hair = hex2num(copytext(hair_c, 6, 8)) M.r_eyes = hex2num(copytext(eye_c, 2, 4)) M.g_eyes = hex2num(copytext(eye_c, 4, 6)) M.b_eyes = hex2num(copytext(eye_c, 6, 8)) M.s_tone = skin_tone - M.h_style = hair_style - M.f_style = facial_hair_style + head_organ.h_style = hair_style + head_organ.f_style = facial_hair_style M.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(last_names)]" M.name = M.real_name diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index f2d76051a37..2d41cd1d202 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -498,6 +498,7 @@ client/proc/one_click_antag() /datum/admins/proc/create_vox_raider(obj/spawn_location, leader_chosen = 0) var/mob/living/carbon/human/new_vox = new(spawn_location.loc, "Vox") + var/obj/item/organ/external/head/head_organ = new_vox.get_organ("head") var/sounds = rand(2,8) var/i = 0 @@ -516,8 +517,8 @@ client/proc/one_click_antag() new_vox.add_language("Vox-pidgin") new_vox.add_language("Galactic Common") new_vox.add_language("Tradeband") - new_vox.h_style = "Short Vox Quills" - new_vox.f_style = "Shaved" + head_organ.h_style = "Short Vox Quills" + head_organ.f_style = "Shaved" for(var/obj/item/organ/external/limb in new_vox.organs) limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index e53af9a5014..06e26861b6d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1631,7 +1631,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("nanoui") nanoui_fancy = !nanoui_fancy - if("ghost_att_anim") + if("ghost_att_anim") show_ghostitem_attack = !show_ghostitem_attack if("UIcolor") @@ -1753,13 +1753,19 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.g_eyes = g_eyes character.b_eyes = b_eyes - character.r_hair = r_hair - character.g_hair = g_hair - character.b_hair = b_hair + //Head-specific + var/obj/item/organ/external/head/H = character.get_organ("head") + H.r_hair = r_hair + H.g_hair = g_hair + H.b_hair = b_hair - character.r_facial = r_facial - character.g_facial = g_facial - character.b_facial = b_facial + H.r_facial = r_facial + H.g_facial = g_facial + H.b_facial = b_facial + + H.h_style = h_style + H.f_style = f_style + //End of head-specific. character.r_skin = r_skin character.g_skin = g_skin @@ -1767,9 +1773,6 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.s_tone = s_tone - character.h_style = h_style - character.f_style = f_style - // Destroy/cyborgize organs for(var/name in organ_data) @@ -1846,10 +1849,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.socks = socks if(character.species.bodyflags & HAS_HEAD_ACCESSORY) - character.r_headacc = r_headacc - character.g_headacc = g_headacc - character.b_headacc = b_headacc - character.ha_style = ha_style + H.r_headacc = r_headacc + H.g_headacc = g_headacc + H.b_headacc = b_headacc + H.ha_style = ha_style if(character.species.bodyflags & HAS_MARKINGS) character.r_markings = r_markings character.g_markings = g_markings diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 071c6032722..13b7a948119 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -176,9 +176,11 @@ /obj/item/clothing/head/kitty/update_icon(var/mob/living/carbon/human/user) if(!istype(user)) return + var/obj/item/organ/external/head/head_organ = user.get_organ("head") + mob = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty") // mob2 = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty2") - Commented out because it seemingly does nothing. - mob.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD) + mob.Blend(rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair), ICON_ADD) // mob2.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD) - Commented out because it seemingly does nothing. var/icon/earbit = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kittyinner") @@ -201,8 +203,9 @@ /obj/item/clothing/head/kitty/mouse/update_icon(var/mob/living/carbon/human/user) if(!istype(user)) return + var/obj/item/organ/external/head/head_organ = user.get_organ("head") mob = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "mousey") - mob.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD) + mob.Blend(rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair), ICON_ADD) var/icon/earbit = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "mouseyinner") mob.Blend(earbit, ICON_OVERLAY) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 8264db804fd..2822fa99933 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -18,16 +18,17 @@ return 1 /mob/living/carbon/human/proc/change_gender(var/gender, var/update_dna = 1) + var/obj/item/organ/external/head/H = organs_by_name["head"] if(src.gender == gender) return src.gender = gender - var/datum/sprite_accessory/hair/current_hair = hair_styles_list[h_style] + var/datum/sprite_accessory/hair/current_hair = hair_styles_list[H.h_style] if(current_hair.gender != NEUTER && current_hair.gender != src.gender) reset_head_hair() - var/datum/sprite_accessory/hair/current_fhair = facial_hair_styles_list[f_style] + var/datum/sprite_accessory/hair/current_fhair = facial_hair_styles_list[H.f_style] if(current_fhair.gender != NEUTER && current_fhair.gender != src.gender) reset_facial_hair() @@ -38,31 +39,33 @@ return 1 /mob/living/carbon/human/proc/change_hair(var/hair_style) + var/obj/item/organ/external/head/H = get_organ("head") if(!hair_style) return - if(h_style == hair_style) + if(H.h_style == hair_style) return if(!(hair_style in hair_styles_list)) return - h_style = hair_style + H.h_style = hair_style update_hair() return 1 /mob/living/carbon/human/proc/change_facial_hair(var/facial_hair_style) + var/obj/item/organ/external/head/H = get_organ("head") if(!facial_hair_style) return - if(f_style == facial_hair_style) + if(H.f_style == facial_hair_style) return if(!(facial_hair_style in facial_hair_styles_list)) return - f_style = facial_hair_style + H.f_style = facial_hair_style update_fhair() return 1 @@ -72,23 +75,24 @@ reset_facial_hair() /mob/living/carbon/human/proc/reset_head_hair() + var/obj/item/organ/external/head/H = get_organ("head") var/list/valid_hairstyles = generate_valid_hairstyles() - if(valid_hairstyles.len) - h_style = pick(valid_hairstyles) + H.h_style = pick(valid_hairstyles) else //this shouldn't happen - h_style = "Bald" + H.h_style = "Bald" update_hair() /mob/living/carbon/human/proc/reset_facial_hair() + var/obj/item/organ/external/head/H = get_organ("head") var/list/valid_facial_hairstyles = generate_valid_facial_hairstyles() if(valid_facial_hairstyles.len) - f_style = pick(valid_facial_hairstyles) + H.f_style = pick(valid_facial_hairstyles) else //this shouldn't happen - f_style = "Shaved" + H.f_style = "Shaved" update_fhair() /mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue) @@ -104,23 +108,25 @@ return 1 /mob/living/carbon/human/proc/change_hair_color(var/red, var/green, var/blue) - if(red == r_eyes && green == g_eyes && blue == b_eyes) + var/obj/item/organ/external/head/H = get_organ("head") + if(red == H.r_hair && green == H.g_hair && blue == H.b_hair) return - r_hair = red - g_hair = green - b_hair = blue + H.r_hair = red + H.g_hair = green + H.b_hair = blue update_hair() return 1 /mob/living/carbon/human/proc/change_facial_hair_color(var/red, var/green, var/blue) - if(red == r_facial && green == g_facial && blue == b_facial) + var/obj/item/organ/external/head/H = get_organ("head") + if(red == H.r_facial && green == H.g_facial && blue == H.b_facial) return - r_facial = red - g_facial = green - b_facial = blue + H.r_facial = red + H.g_facial = green + H.b_facial = blue update_fhair() return 1 @@ -172,17 +178,17 @@ var/list/valid_hairstyles = new() for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] + var/obj/item/organ/external/head/H = organs_by_name["head"] if(gender == MALE && S.gender == FEMALE) continue if(gender == FEMALE && S.gender == MALE) continue - if(species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head... - var/obj/item/organ/external/head/H = organs_by_name["head"] + if(H.species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] if(!H) return - if(species.name in S.species_allowed) //If this is a hairstyle native to the user's species... + if(H.species.name in S.species_allowed) //If this is a hairstyle native to the user's species... if(robohead.is_monitor && (robohead.company in S.models_allowed)) //Check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_hairstyles += hairstyle //Give them their hairstyles if they do. continue @@ -195,8 +201,8 @@ if("Human" in S.species_allowed) //If the user has a robotic head and the hairstyle can fit humans, let them use it as a wig for their humanoid robot head. valid_hairstyles += hairstyle continue - else - if(!(species.name in S.species_allowed)) //If the user is not a species who can have robotic heads, use the default handling. + else //If the user is not a species who can have robotic heads, use the default handling. + if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the hair style allows, skip it. Otherwise, add it to the list. continue valid_hairstyles += hairstyle @@ -206,17 +212,17 @@ var/list/valid_facial_hairstyles = new() for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] + var/obj/item/organ/external/head/H = organs_by_name["head"] if(gender == MALE && S.gender == FEMALE) continue if(gender == FEMALE && S.gender == MALE) continue - if(species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head... - var/obj/item/organ/external/head/H = organs_by_name["head"] + if(H.species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] if(!H) continue // No head, no hair - if(species.name in S.species_allowed) //If this is a facial hair style native to the user's species... + if(H.species.name in S.species_allowed) //If this is a facial hair style native to the user's species... if(robohead.is_monitor && (robohead.company in S.models_allowed)) //Check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_facial_hairstyles += facialhairstyle //Give them their facial hair styles if they do. continue @@ -231,7 +237,7 @@ valid_facial_hairstyles += facialhairstyle continue else //If the user is not a species who can have robotic heads, use the default handling. - if(!(species.name in S.species_allowed)) + if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the facial hair style allows, skip it. Otherwise, add it to the list. continue valid_facial_hairstyles += facialhairstyle diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index aa31c912841..fce12362d73 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -145,12 +145,13 @@ return ..(gibbed) /mob/living/carbon/human/proc/makeSkeleton() + var/obj/item/organ/external/head/H = get_organ("head") if(SKELETON in src.mutations) return - if(f_style) - f_style = "Shaved" - if(h_style) - h_style = "Bald" + if(H.f_style) + H.f_style = "Shaved" + if(H.h_style) + H.h_style = "Bald" update_fhair(0) update_hair(0) @@ -162,12 +163,13 @@ return /mob/living/carbon/human/proc/ChangeToHusk() + var/obj/item/organ/external/head/H = organs_by_name["head"] if(HUSK in mutations) return - if(f_style) - f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE - if(h_style) - h_style = "Bald" + if(H.f_style) + H.f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE + if(H.h_style) + H.h_style = "Bald" update_fhair(0) update_hair(0) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 3e5cb90f380..f78a80a3c3c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -74,38 +74,46 @@ status_flags = GODMODE|CANPUSH /mob/living/carbon/human/skrell/New(var/new_loc) - h_style = "Skrell Male Tentacles" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Skrell Male Tentacles" ..(new_loc, "Skrell") /mob/living/carbon/human/tajaran/New(var/new_loc) - ha_style = "Tajaran Ears" + var/obj/item/organ/external/head/H = get_organ("head") + H.ha_style = "Tajaran Ears" ..(new_loc, "Tajaran") /mob/living/carbon/human/vulpkanin/New(var/new_loc) - h_style = "Bald" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Bald" ..(new_loc, "Vulpkanin") /mob/living/carbon/human/unathi/New(var/new_loc) - h_style = "Unathi Horns" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Unathi Horns" ..(new_loc, "Unathi") /mob/living/carbon/human/vox/New(var/new_loc) - h_style = "Short Vox Quills" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Short Vox Quills" ..(new_loc, "Vox") /mob/living/carbon/human/voxarmalis/New(var/new_loc) - h_style = "Bald" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Bald" ..(new_loc, "Vox Armalis") /mob/living/carbon/human/skeleton/New(var/new_loc) - h_style = "Bald" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Bald" ..(new_loc, "Skeleton") /mob/living/carbon/human/kidan/New(var/new_loc) ..(new_loc, "Kidan") /mob/living/carbon/human/plasma/New(var/new_loc) - h_style = "Bald" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Bald" ..(new_loc, "Plasmaman") /mob/living/carbon/human/slime/New(var/new_loc) @@ -121,31 +129,38 @@ ..(new_loc, "Human") /mob/living/carbon/human/diona/New(var/new_loc) - h_style = "Bald" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Bald" ..(new_loc, "Diona") /mob/living/carbon/human/machine/New(var/new_loc) - h_style = "blue IPC screen" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Blue IPC Screen" ..(new_loc, "Machine") /mob/living/carbon/human/shadow/New(var/new_loc) - h_style = "Bald" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Bald" ..(new_loc, "Shadow") /mob/living/carbon/human/golem/New(var/new_loc) - h_style = "Bald" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Bald" ..(new_loc, "Golem") /mob/living/carbon/human/wryn/New(var/new_loc) - h_style = "Antennae" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Antennae" ..(new_loc, "Wryn") /mob/living/carbon/human/nucleation/New(var/new_loc) - h_style = "Nucleation Crystals" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Nucleation Crystals" ..(new_loc, "Nucleation") /mob/living/carbon/human/drask/New(var/new_loc) - h_style = "Bald" + var/obj/item/organ/external/head/H = get_organ("head") + H.h_style = "Bald" ..(new_loc, "Drask") /mob/living/carbon/human/monkey/New(var/new_loc) @@ -1601,9 +1616,8 @@ return if(species.flags & ALL_RPARTS) //If they can have a fully cybernetic body... - var/obj/item/organ/external/head/H = organs_by_name["head"] - var/datum/robolimb/robohead = all_robolimbs[H.model] - if(!H) + var/datum/robolimb/robohead = all_robolimbs[head_organ.model] + if(!head_organ) return if(!robohead.is_monitor) //If they've got a prosthetic head and it isn't a monitor, they've no screen to adjust. Instead, let them change the colour of their optics! var/optic_colour = input(src, "Select optic colour", rgb(r_markings, g_markings, b_markings)) as color|null @@ -1620,15 +1634,15 @@ var/list/hair = list() for(var/i in hair_styles_list) var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i] - if((species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. + if((head_organ.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. hair += i - var/new_style = input(src, "Select a monitor display", "Monitor Display", h_style) as null|anything in hair + var/new_style = input(src, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair if(incapacitated()) to_chat(src, "You were interrupted while changing your monitor display.") return if(new_style) - h_style = new_style + head_organ.h_style = new_style update_hair() diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index e2ebed386b3..6f106f5e125 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -9,24 +9,6 @@ var/global/default_martial_art = new/datum/martial_art var/b_markings = 0 var/m_style = "None" - //Hair colour and style - var/r_hair = 0 - var/g_hair = 0 - var/b_hair = 0 - var/h_style = "Bald" - - //Head accessory colour and style - var/r_headacc = 0 - var/g_headacc = 0 - var/b_headacc = 0 - var/ha_style = "None" - - //Facial hair colour and style - var/r_facial = 0 - var/g_facial = 0 - var/b_facial = 0 - var/f_style = "Shaved" - //Eye colour var/r_eyes = 0 var/g_eyes = 0 diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm index a7735a00db9..ed02ee5465a 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/apollo.dm @@ -54,6 +54,7 @@ to_chat(C, "It feels like part of you has died.") /datum/species/wryn/handle_attack_hand(var/mob/living/carbon/human/H, var/mob/living/carbon/human/M) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") if(M.a_intent == I_HARM) if(H.handcuffed) if(!H.get_int_organ(/obj/item/organ/internal/wryn/hivenode)) return @@ -71,7 +72,7 @@ to_chat(M, "You hear a loud crunch as you mercilessly pull off [H]'s antennae.") to_chat(H, "You hear a loud crunch as your antennae is ripped off your head by [M].") to_chat(H, "It's so quiet...") - H.h_style = "Bald" + head_organ.h_style = "Bald" H.update_hair() M.attack_log += text("\[[time_stamp()]\] removed antennae [H.name] ([H.ckey])") @@ -87,7 +88,7 @@ blurb = "A sub-race of unforunates who have been exposed to too much supermatter radiation. As a result, \ supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \ has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \ - negating the need for the individual to breath. Their massive change in biology, however, renders most medicines \ + negating the need for the individual to breathe. Their massive change in biology, however, renders most medicines \ obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \ and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \ way as lepers were back on Earth." diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 26c6ddb0c57..cce8b5c46ec 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -791,6 +791,8 @@ ) /datum/species/machine/handle_death(var/mob/living/carbon/human/H) - H.h_style = "" + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + head_organ.h_style = "Bald" + head_organ.f_style = "Shaved" spawn(100) if(H) H.update_hair() \ 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 004f54a45ba..c885793f82c 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -393,13 +393,13 @@ var/global/list/damage_icon_parts = list() //base icons var/icon/head_accessory_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") - if(ha_style && (src.species.bodyflags & HAS_HEAD_ACCESSORY)) - var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[ha_style] + if(head_organ.ha_style && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY)) + var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[head_organ.ha_style] if(head_accessory_style && head_accessory_style.species_allowed) - if(src.species.name in head_accessory_style.species_allowed) + if(head_organ.species.name in head_accessory_style.species_allowed) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) - head_accessory_s.Blend(rgb(r_headacc, g_headacc, b_headacc), ICON_ADD) + head_accessory_s.Blend(rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc), ICON_ADD) head_accessory_standing = head_accessory_s //head_accessory_standing.Blend(head_accessory_s, ICON_OVERLAY) //Having it this way preserves animations. Useful for animated antennae. else @@ -429,17 +429,17 @@ var/global/list/damage_icon_parts = list() var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s") //var/icon/debrained_s = new /icon("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s") - if(h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()))) - var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] + if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()))) + var/datum/sprite_accessory/hair_style = hair_styles_list[head_organ.h_style] //if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN // hair_standing.Blend(debrained_s, ICON_OVERLAY) if(hair_style && hair_style.species_allowed) - if((src.species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS)) + if((head_organ.species.name in hair_style.species_allowed) || (head_organ.species.flags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(src.get_species() == "Slime People") // I am el worstos + if(head_organ.species.name == "Slime People") // I am el worstos hair_s.Blend(rgb(r_skin, g_skin, b_skin, 160), ICON_AND) else if(hair_style.do_colouration) - hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) + hair_s.Blend(rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair), ICON_ADD) hair_standing = hair_s //hair_standing.Blend(hair_s, ICON_OVERLAY) //Having it this way preserves animations. Useful for IPC screens. @@ -470,15 +470,15 @@ var/global/list/damage_icon_parts = list() //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(head_organ.f_style) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[head_organ.f_style] if(facial_hair_style && facial_hair_style.species_allowed) - if((src.species.name in facial_hair_style.species_allowed) || (src.species.flags & ALL_RPARTS)) + if((head_organ.species.name in facial_hair_style.species_allowed) || (head_organ.species.flags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(src.get_species() == "Slime People") // I am el worstos + if(head_organ.species.name == "Slime People") // I am el worstos facial_s.Blend(rgb(r_skin, g_skin, b_skin, 160), ICON_AND) else if(facial_hair_style.do_colouration) - facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) + facial_s.Blend(rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial), ICON_ADD) face_standing.Blend(facial_s, ICON_OVERLAY) else //warning("Invalid f_style for [species.name]: [f_style]") @@ -1266,22 +1266,23 @@ var/global/list/damage_icon_parts = list() //gender no longer matters for the mouth, although there should probably be seperate base head icons. // var/g = "m" // if (gender == FEMALE) g = "f" - + var/obj/item/organ/external/head/H = get_organ("head") //base icons var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l") - if(f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] + + if(H.f_style) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] if(facial_hair_style) var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l") - facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) + facial_l.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) face_lying.Blend(facial_l, ICON_OVERLAY) - if(h_style) - var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] + if(H.h_style) + var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] if(hair_style) var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l") - hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) + hair_l.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) face_lying.Blend(hair_l, ICON_OVERLAY) //Eyes diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index 08f5089a200..1ad57bd787d 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -148,6 +148,7 @@ /obj/effect/proc_holder/spell/targeted/recruit/cast(list/targets) for(var/mob/living/carbon/human/target in targets) + var/obj/item/organ/external/head/head_organ = target.get_organ("head") if(ticker.mode.greyshirts.len >= 3) to_chat(usr, "You have already recruited the maximum number of henchmen.") if(!in_range(usr, target)) @@ -210,8 +211,8 @@ to_chat(target, "You may not harm other Greyshirt or [usr]. However, you do not need to obey other Greyshirts.") ticker.mode.greyshirts += target.mind target.set_species("Human") - target.h_style = "Bald" - target.f_style = "Shaved" + head_organ.h_style = "Bald" + head_organ.f_style = "Shaved" target.s_tone = 35 target.r_eyes = 1 target.b_eyes = 1 diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index e0fbfcdf91b..15452598ed5 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -886,12 +886,12 @@ species_allowed = list("Vox") vox_quills_fluff - name = "Fluffy Quills" + name = "Fluffy Vox Quills" icon_state = "vox_afro" species_allowed = list("Vox") vox_quills_mohawk - name = "Quill Mohawk" + name = "Vox Quill Mohawk" icon_state = "vox_mohawk" species_allowed = list("Vox") @@ -910,6 +910,11 @@ icon_state = "vox_nights" species_allowed = list("Vox") + vox_razor + name = "Vox Razorback" + icon_state = "vox_razor" + species_allowed = list("Vox") + // Apollo-specific //Wryn antennae diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 606dcade9c9..4868bfdc7c5 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -2,6 +2,7 @@ name = "Appearance Editor" var/flags = APPEARANCE_ALL_HAIR var/mob/living/carbon/human/owner = null + var/obj/item/organ/external/head/head_organ = null var/list/valid_species = list() var/list/valid_hairstyles = list() var/list/valid_facial_hairstyles = list() @@ -13,6 +14,7 @@ /datum/nano_module/appearance_changer/New(var/location, var/mob/living/carbon/human/H, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list()) ..() owner = H + head_organ = owner.get_organ("head") src.check_whitelist = check_species_whitelist src.whitelist = species_whitelist src.blacklist = species_blacklist @@ -54,7 +56,7 @@ return 1 if(href_list["hair_color"]) if(can_change(APPEARANCE_HAIR_COLOR)) - var/new_hair = input("Please select hair color.", "Hair Color", rgb(owner.r_hair, owner.g_hair, owner.b_hair)) as color|null + var/new_hair = input("Please select hair color.", "Hair Color", rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair)) as color|null if(new_hair && can_still_topic(state)) var/r_hair = hex2num(copytext(new_hair, 2, 4)) var/g_hair = hex2num(copytext(new_hair, 4, 6)) @@ -69,7 +71,7 @@ return 1 if(href_list["facial_hair_color"]) if(can_change(APPEARANCE_FACIAL_HAIR_COLOR)) - var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(owner.r_facial, owner.g_facial, owner.b_facial)) as color|null + var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial)) as color|null if(new_facial && can_still_topic(state)) var/r_facial = hex2num(copytext(new_facial, 2, 4)) var/g_facial = hex2num(copytext(new_facial, 4, 6)) @@ -113,7 +115,7 @@ for(var/hair_style in valid_hairstyles) hair_styles[++hair_styles.len] = list("hairstyle" = hair_style) data["hair_styles"] = hair_styles - data["hair_style"] = owner.h_style + data["hair_style"] = head_organ.h_style data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) if(data["change_facial_hair"]) @@ -121,7 +123,7 @@ for(var/facial_hair_style in valid_facial_hairstyles) facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style) data["facial_hair_styles"] = facial_hair_styles - data["facial_hair_style"] = owner.f_style + data["facial_hair_style"] = head_organ.f_style data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) diff --git a/code/modules/reagents/newchem/other.dm b/code/modules/reagents/newchem/other.dm index c26d8bbe983..4fe016f49ba 100644 --- a/code/modules/reagents/newchem/other.dm +++ b/code/modules/reagents/newchem/other.dm @@ -198,12 +198,13 @@ datum/reagent/hair_dye datum/reagent/hair_dye/reaction_mob(var/mob/living/M, var/volume) if(M && ishuman(M)) var/mob/living/carbon/human/H = M - H.r_facial = rand(0,255) - H.g_facial = rand(0,255) - H.b_facial = rand(0,255) - H.r_hair = rand(0,255) - H.g_hair = rand(0,255) - H.b_hair = rand(0,255) + var/obj/item/organ/external/head/head_organ = H.organs_by_name["head"] + head_organ.r_facial = rand(0,255) + head_organ.g_facial = rand(0,255) + head_organ.b_facial = rand(0,255) + head_organ.r_hair = rand(0,255) + head_organ.g_hair = rand(0,255) + head_organ.b_hair = rand(0,255) H.update_hair() H.update_fhair() ..() @@ -228,8 +229,9 @@ datum/reagent/hairgrownium datum/reagent/hairgrownium/reaction_mob(var/mob/living/M, var/volume) if(M && ishuman(M)) var/mob/living/carbon/human/H = M - H.h_style = random_hair_style(H.gender, H.species) - H.f_style = random_facial_hair_style(H.gender, H.species) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + head_organ.h_style = random_hair_style(H.gender, head_organ.species) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species) H.update_hair() H.update_fhair() ..() @@ -256,8 +258,9 @@ datum/reagent/super_hairgrownium/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom if(M && ishuman(M)) var/mob/living/carbon/human/H = M - H.h_style = "Very Long Hair" - H.f_style = "Very Long Beard" + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + head_organ.h_style = "Very Long Hair" + head_organ.f_style = "Very Long Beard" H.update_hair() H.update_fhair() if(!H.wear_mask || H.wear_mask && !istype(H.wear_mask, /obj/item/clothing/mask/fakemoustache)) diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index 3386f4b9366..90f2d9afed0 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -97,10 +97,12 @@ E.forceMove(target) if(target.get_species() == "Machine")//as this is the only step needed for ipc put togethers if(target_zone == "head") - var/obj/item/organ/external/head/H = target.organs_by_name["head"] + var/obj/item/organ/external/head/H = target.get_organ("head") var/datum/robolimb/robohead = all_robolimbs[H.model] if(robohead.is_monitor) //Ensures that if an IPC gets a head that's got a human hair wig attached to their body, the hair won't wipe. - target.h_style = "" + H.h_style = "" + H.f_style = "" + target.m_style = "" E.status &= ~ORGAN_DESTROYED if(E.children) for(var/obj/item/organ/external/C in E.children) diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index db6ffd81a2a..0488d768adf 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -54,6 +54,7 @@ var/global/list/limb_icon_cache = list() overlays.Cut() if(!owner) return + var/obj/item/organ/external/head/H = owner.get_organ("head") if(species.has_organ["eyes"]) var/obj/item/organ/internal/eyes/eyes = owner.get_int_organ(/obj/item/organ/internal/eyes)//owner.internal_organs_by_name["eyes"] @@ -79,32 +80,32 @@ var/global/list/limb_icon_cache = list() markings_s.Blend(rgb(owner.r_markings, owner.g_markings, owner.b_markings), ICON_ADD) overlays |= markings_s - if(owner.ha_style) - var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[owner.ha_style] - if(head_accessory_style && head_accessory_style.species_allowed && (species.name in head_accessory_style.species_allowed)) + if(H.ha_style) + var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[H.ha_style] + if(head_accessory_style && head_accessory_style.species_allowed && (H.species.name in head_accessory_style.species_allowed)) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) - head_accessory_s.Blend(rgb(owner.r_headacc, owner.g_headacc, owner.b_headacc), ICON_ADD) + head_accessory_s.Blend(rgb(H.r_headacc, H.g_headacc, H.b_headacc), ICON_ADD) overlays |= head_accessory_s - if(owner.f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (species.name in facial_hair_style.species_allowed)) || (src.species.flags & ALL_RPARTS))) + if(H.f_style) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] + if(facial_hair_style && ((facial_hair_style.species_allowed && (H.species.name in facial_hair_style.species_allowed)) || (src.species.flags & ALL_RPARTS))) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(species.name == "Slime People") // I am el worstos + if(H.species.name == "Slime People") // I am el worstos facial_s.Blend(rgb(owner.r_skin, owner.g_skin, owner.b_skin, 160), ICON_AND) else if(facial_hair_style.do_colouration) - facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD) + facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) overlays |= facial_s - if(owner.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style] - if(hair_style && ((species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS))) + if(H.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) + var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] + if(hair_style && ((H.species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS))) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(species.name == "Slime People") // I am el worstos + if(H.species.name == "Slime People") // I am el worstos hair_s.Blend(rgb(owner.r_skin, owner.g_skin, owner.b_skin, 160), ICON_AND) else if(hair_style.do_colouration) - hair_s.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD) + hair_s.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) overlays |= hair_s return mob_icon diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 248da9d1154..fd61410bdef 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -499,18 +499,19 @@ if(istype(owner, /mob/living/carbon/human)) var/mob/living/carbon/human/H = owner - if(!(H.h_style == "Very Long Hair" || H.h_style == "Mowhawk")) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + if(!(head_organ.h_style == "Very Long Hair" || head_organ.h_style == "Mowhawk")) if(prob(10)) - H.h_style = "Mohawk" + head_organ.h_style = "Mohawk" else - H.h_style = "Very Long Hair" - H.r_hair = 216 - H.g_hair = 192 - H.b_hair = 120 + head_organ.h_style = "Very Long Hair" + head_organ.r_hair = 216 + head_organ.g_hair = 192 + head_organ.b_hair = 120 H.update_hair() - if(!(H.f_style == "Very Long Beard")) - H.f_style = "Very Long Beard" - H.r_facial = 216 - H.g_facial = 192 - H.b_facial = 120 + if(!(head_organ.f_style == "Very Long Beard")) + head_organ.f_style = "Very Long Beard" + head_organ.r_facial = 216 + head_organ.g_facial = 192 + head_organ.b_facial = 120 H.update_fhair() \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index c9cbbb17906..d481ba1b7ae 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -141,6 +141,24 @@ encased = "skull" var/can_intake_reagents = 1 + //Hair colour and style + var/r_hair = 0 + var/g_hair = 0 + var/b_hair = 0 + var/h_style = "Bald" + + //Head accessory colour and style + var/r_headacc = 0 + var/g_headacc = 0 + var/b_headacc = 0 + var/ha_style = "None" + + //Facial hair colour and style + var/r_facial = 0 + var/g_facial = 0 + var/b_facial = 0 + var/f_style = "Shaved" + /obj/item/organ/external/head/remove() if(owner) if(!istype(dna)) diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 3cd59fe3f741bfa74563dddbfb8cde1a2e8feb77..f140d02be968f598ea4466a99a043eaf7619229e 100644 GIT binary patch delta 27468 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 Fe*+S}khcH; delta 27463 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 Date: Sat, 30 Apr 2016 20:15:53 -0400 Subject: [PATCH 02/10] Fixes Runtime When Creating new Humans It runtimed because when there was /mob/living/carbon/human/vulpkanin/New(var/new_loc) >>>>>var/obj/item/organ/external/head/H = get_organ("head") >>>>>H.h_style = "Bald" >>>>>..(new_loc, "Vulpkanin") in human/human.dm, it'd error out because the mob doesn't have those organs at this point-- so I just moved the definition of what hair/head accessory styles these basic default mobs get to the species definition, where it'll accomplish the same thing as it used to while still using the head-hair system appropriately --- code/modules/mob/living/carbon/human/human.dm | 39 +++++-------------- .../mob/living/carbon/human/species/apollo.dm | 5 +++ .../living/carbon/human/species/species.dm | 6 ++- .../living/carbon/human/species/station.dm | 10 +++++ 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index f78a80a3c3c..90fed057057 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -74,46 +74,30 @@ status_flags = GODMODE|CANPUSH /mob/living/carbon/human/skrell/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Skrell Male Tentacles" ..(new_loc, "Skrell") /mob/living/carbon/human/tajaran/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.ha_style = "Tajaran Ears" ..(new_loc, "Tajaran") /mob/living/carbon/human/vulpkanin/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Bald" ..(new_loc, "Vulpkanin") /mob/living/carbon/human/unathi/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Unathi Horns" ..(new_loc, "Unathi") /mob/living/carbon/human/vox/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Short Vox Quills" ..(new_loc, "Vox") /mob/living/carbon/human/voxarmalis/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Bald" ..(new_loc, "Vox Armalis") /mob/living/carbon/human/skeleton/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Bald" ..(new_loc, "Skeleton") /mob/living/carbon/human/kidan/New(var/new_loc) ..(new_loc, "Kidan") /mob/living/carbon/human/plasma/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Bald" ..(new_loc, "Plasmaman") /mob/living/carbon/human/slime/New(var/new_loc) @@ -129,38 +113,24 @@ ..(new_loc, "Human") /mob/living/carbon/human/diona/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Bald" ..(new_loc, "Diona") /mob/living/carbon/human/machine/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Blue IPC Screen" ..(new_loc, "Machine") /mob/living/carbon/human/shadow/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Bald" ..(new_loc, "Shadow") /mob/living/carbon/human/golem/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Bald" ..(new_loc, "Golem") /mob/living/carbon/human/wryn/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Antennae" ..(new_loc, "Wryn") /mob/living/carbon/human/nucleation/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Nucleation Crystals" ..(new_loc, "Nucleation") /mob/living/carbon/human/drask/New(var/new_loc) - var/obj/item/organ/external/head/H = get_organ("head") - H.h_style = "Bald" ..(new_loc, "Drask") /mob/living/carbon/human/monkey/New(var/new_loc) @@ -1520,6 +1490,15 @@ species.create_organs(src) + //Handle default hair/head accessories for created mobs. + var/obj/item/organ/external/head/H = get_organ("head") + if(species.default_hair) + H.h_style = species.default_hair + if(species.default_fhair) + H.f_style = species.default_fhair + if(species.default_headacc) + H.ha_style = species.default_headacc + if(!dna) dna = new /datum/dna(null) dna.species = species.name diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm index ed02ee5465a..5642eedbcbe 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/apollo.dm @@ -45,6 +45,8 @@ base_color = "#704300" flesh_color = "#704300" blood_color = "#FFFF99" + //Default styles for created mobs. + default_hair = "Antennae" /datum/species/wryn/handle_death(var/mob/living/carbon/human/H) @@ -98,6 +100,9 @@ flags = IS_WHITELISTED | NO_BREATHE | NO_BLOOD | NO_PAIN | HAS_LIPS | NO_SCAN dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet + //Default styles for created mobs. + default_hair = "Nucleation Crystals" + reagent_tag = PROCESS_ORG has_organ = list( "heart" = /obj/item/organ/internal/heart, diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 03091a7e50f..7430dde4331 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -118,6 +118,11 @@ var/male_scream_sound = 'sound/goonstation/voice/male_scream.ogg' var/female_scream_sound = 'sound/goonstation/voice/female_scream.ogg' + //Default hair/headacc style vars. + var/default_hair = "Bald" //Default hair style for newly created humans unless otherwise set. + var/default_fhair = "Shaved" //Default facial hair style for newly created humans unless otherwise set. + var/default_headacc = "None" //Default head accessory style for newly created humans unless otherwise set. + // Determines the organs that the species spawns with and var/list/has_organ = list( // which required-organ checks are conducted. "heart" = /obj/item/organ/internal/heart, @@ -158,7 +163,6 @@ /datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. - for(var/obj/item/organ/internal/iorgan in H.internal_organs) if(iorgan in H.internal_organs) qdel(iorgan) diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index cce8b5c46ec..6755ad5e8ef 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -55,6 +55,8 @@ flesh_color = "#34AF10" reagent_tag = PROCESS_ORG base_color = "#066000" + //Default styles for created mobs. + default_hair = "Unathi Horns" allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) @@ -109,6 +111,8 @@ reagent_tag = PROCESS_ORG flesh_color = "#AFA59E" base_color = "#333333" + //Default styles for created mobs. + default_headacc = "Tajaran Ears" allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/chick, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) @@ -189,6 +193,8 @@ dietflags = DIET_HERB flesh_color = "#8CD7A3" blood_color = "#1D2CBF" + //Default styles for created mobs. + default_hair = "Skrell Male Tentacles" reagent_tag = PROCESS_ORG suicide_messages = list( @@ -251,6 +257,8 @@ blood_color = "#2299FC" flesh_color = "#808D11" + //Default styles for created mobs. + default_hair = "Short Vox Quills" reagent_tag = PROCESS_ORG scream_verb = "shrieks" @@ -751,6 +759,8 @@ dietflags = 0 //IPCs can't eat, so no diet blood_color = "#1F181F" flesh_color = "#AAAAAA" + //Default styles for created mobs. + default_hair = "Blue IPC Screen" virus_immune = 1 can_revive_by_healing = 1 reagent_tag = PROCESS_SYN From 73dbbed70e14af79894a34b10ffda8ec7d6ee319 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Sat, 30 Apr 2016 20:48:58 -0400 Subject: [PATCH 03/10] Cutting Someone's Facial Hair will now Update Facial Hair --- code/game/objects/items/weapons/scissors.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm index 343c3788bdc..626e1576623 100644 --- a/code/game/objects/items/weapons/scissors.dm +++ b/code/game/objects/items/weapons/scissors.dm @@ -89,6 +89,7 @@ C.h_style = h_new_style H.update_hair() + H.update_fhair() user.visible_message("[user] finishes cutting [M]'s hair!") /obj/item/weapon/scissors/safety //Totally safe, I assure you. From 7205d3a0e39478baeee7bcf49146025b52adfef6 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Sat, 30 Apr 2016 22:05:57 -0400 Subject: [PATCH 04/10] Hairgrownium and Super Hairgrownium now work on All Species, refactored so if it produces random hair styles for a non-human, it won't do so repeatedly until the reagent is depleted. Also means that species that need breath masks to live won't be killed by infinite fake moustaches. --- code/__HELPERS/mobs.dm | 2 +- code/modules/reagents/newchem/other.dm | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index f8980d61ddd..3d1648fa77a 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -52,7 +52,7 @@ proc/random_hair_style(var/gender, species = "Human") if(valid_hairstyles.len) h_style = pick(valid_hairstyles) - return h_style + return h_style proc/GetOppositeDir(var/dir) switch(dir) diff --git a/code/modules/reagents/newchem/other.dm b/code/modules/reagents/newchem/other.dm index 4fe016f49ba..0fa7c579041 100644 --- a/code/modules/reagents/newchem/other.dm +++ b/code/modules/reagents/newchem/other.dm @@ -198,7 +198,7 @@ datum/reagent/hair_dye datum/reagent/hair_dye/reaction_mob(var/mob/living/M, var/volume) if(M && ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/external/head/head_organ = H.organs_by_name["head"] + var/obj/item/organ/external/head/head_organ = H.get_organ("head") head_organ.r_facial = rand(0,255) head_organ.g_facial = rand(0,255) head_organ.b_facial = rand(0,255) @@ -230,8 +230,8 @@ datum/reagent/hairgrownium/reaction_mob(var/mob/living/M, var/volume) if(M && ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/head/head_organ = H.get_organ("head") - head_organ.h_style = random_hair_style(H.gender, head_organ.species) - head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species) + head_organ.h_style = random_hair_style(H.gender, head_organ.species.name) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species.name) H.update_hair() H.update_fhair() ..() @@ -254,13 +254,21 @@ datum/reagent/super_hairgrownium result_amount = 3 mix_message = "The liquid becomes amazingly furry and smells peculiar." -datum/reagent/super_hairgrownium/on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom +datum/reagent/super_hairgrownium/reaction_mob(var/mob/living/M, var/volume) if(M && ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/head/head_organ = H.get_organ("head") - head_organ.h_style = "Very Long Hair" - head_organ.f_style = "Very Long Beard" + var/datum/sprite_accessory/tmp_hair_style = hair_styles_list["Very Long Hair"] + var/datum/sprite_accessory/tmp_facial_hair_style = facial_hair_styles_list["Very Long Beard"] + + if(head_organ.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. + head_organ.h_style = "Very Long Hair" + else //Otherwise, give them a random hair style. + head_organ.h_style = random_hair_style(H.gender, head_organ.species.name) + if(head_organ.species.name in tmp_facial_hair_style.species_allowed) //If 'Very Long Beard' is a style the person's species can have, give it to them. + head_organ.f_style = "Very Long Beard" + else //Otherwise, give them a random facial hair style. + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species.name) H.update_hair() H.update_fhair() if(!H.wear_mask || H.wear_mask && !istype(H.wear_mask, /obj/item/clothing/mask/fakemoustache)) From 8cca627918484789c0374b941ade9cea87db2f91 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Sun, 1 May 2016 18:40:50 -0400 Subject: [PATCH 05/10] Fixes Bug where Facial Hair Wouldn't Update on Death. --- code/modules/mob/living/carbon/human/species/station.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 6755ad5e8ef..8bd4386c3f8 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -805,4 +805,6 @@ head_organ.h_style = "Bald" head_organ.f_style = "Shaved" spawn(100) - if(H) H.update_hair() \ No newline at end of file + if(H) + H.update_hair() + H.update_fhair() \ No newline at end of file From 9015f11f41622b0252b35d93100bcfc66b5860d6 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Mon, 2 May 2016 18:13:31 -0400 Subject: [PATCH 06/10] Fixes Morph Being Borked + Additional Features for Morph and C.M.A. Before it wouldn't update skin colour or eye colour, and ended up breaking the sprite such that C.M.A wouldn't have an effect on it after. Now it works perfectly fine, C.M.A works just fine too before and after STAGE 2: Refactors Morph So you change gender first and thus can actually access male beard styles, then you choose hair style and hair colour, then beard style and beard colour, then skin tone or body colour at the very end. STAGE 3 Adds Head Accessory, Head Accessory colour, marking style and body accessory to Morph and C.M.A. --- code/__DEFINES/mob.dm | 6 +- code/game/dna/genes/vg_powers.dm | 142 +++++++++++------- code/game/objects/structures/mirror.dm | 1 + .../mob/living/carbon/human/appearance.dm | 123 ++++++++++++++- .../mob/new_player/sprite_accessories.dm | 8 +- code/modules/nano/modules/human_appearance.dm | 89 ++++++++++- nano/templates/appearance_changer.tmpl | 47 +++++- 7 files changed, 350 insertions(+), 66 deletions(-) diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm index 2bdb3432f69..78439abcb07 100644 --- a/code/__DEFINES/mob.dm +++ b/code/__DEFINES/mob.dm @@ -76,7 +76,11 @@ #define APPEARANCE_FACIAL_HAIR_COLOR 128 #define APPEARANCE_EYE_COLOR 256 #define APPEARANCE_ALL_HAIR APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR -#define APPEARANCE_ALL 511 +#define APPEARANCE_HEAD_ACCESSORY 512 +#define APPEARANCE_MARKINGS 1024 +#define APPEARANCE_BODY_ACCESSORY 2048 +#define APPEARANCE_ALL_BODY APPEARANCE_ALL_HAIR|APPEARANCE_HEAD_ACCESSORY|APPEARANCE_MARKINGS|APPEARANCE_BODY_ACCESSORY +#define APPEARANCE_ALL 4095 // Intents #define I_HELP "help" diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index 5511642e53e..13f334c010b 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -39,69 +39,99 @@ var/mob/living/carbon/human/M=usr var/obj/item/organ/external/head/head_organ = M.get_organ("head") - var/new_facial = input("Please select facial hair color.", "Character Generation",rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial)) as null|color - if(new_facial) - head_organ.r_facial = hex2num(copytext(new_facial, 2, 4)) - head_organ.g_facial = hex2num(copytext(new_facial, 4, 6)) - head_organ.b_facial = hex2num(copytext(new_facial, 6, 8)) - - var/new_hair = input("Please select hair color.", "Character Generation",rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair)) as null|color - if(new_facial) - head_organ.r_hair = hex2num(copytext(new_hair, 2, 4)) - head_organ.g_hair = hex2num(copytext(new_hair, 4, 6)) - head_organ.b_hair = hex2num(copytext(new_hair, 6, 8)) - - var/new_eyes = input("Please select eye color.", "Character Generation",rgb(M.r_eyes,M.g_eyes,M.b_eyes)) as null|color - if(new_eyes) - M.r_eyes = hex2num(copytext(new_eyes, 2, 4)) - M.g_eyes = hex2num(copytext(new_eyes, 4, 6)) - M.b_eyes = hex2num(copytext(new_eyes, 6, 8)) - - var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-M.s_tone]") as null|text - - if (!new_tone) - new_tone = 35 - M.s_tone = max(min(round(text2num(new_tone)), 220), 1) - M.s_tone = -M.s_tone + 35 - - // hair - var/list/all_hairs = subtypesof(/datum/sprite_accessory/hair) - var/list/hairs = list() - - // loop through potential hairs - for(var/x in all_hairs) - var/datum/sprite_accessory/hair/H = new x // create new hair datum based on type x - hairs.Add(H.name) // add hair name to hairs - qdel(H) // delete the hair after it's all done - - var/new_style = input("Please select hair style", "Character Generation", head_organ.h_style) as null|anything in hairs - - // if new style selected (not cancel) - if (new_style) - head_organ.h_style = new_style - - // facial hair - var/list/all_fhairs = subtypesof(/datum/sprite_accessory/facial_hair) - var/list/fhairs = list() - - for(var/x in all_fhairs) - var/datum/sprite_accessory/facial_hair/H = new x - fhairs.Add(H.name) - qdel(H) - - new_style = input("Please select facial style", "Character Generation", head_organ.f_style) as null|anything in fhairs - - if(new_style) - head_organ.f_style = new_style - var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") if (new_gender) if(new_gender == "Male") M.change_gender(MALE) else M.change_gender(FEMALE) + + var/new_eyes = input("Please select eye color.", "Character Generation", rgb(M.r_eyes,M.g_eyes,M.b_eyes)) as null|color + if(new_eyes) + M.r_eyes = hex2num(copytext(new_eyes, 2, 4)) + M.g_eyes = hex2num(copytext(new_eyes, 4, 6)) + M.b_eyes = hex2num(copytext(new_eyes, 6, 8)) + M.change_eye_color(M.r_eyes, M.g_eyes, M.b_eyes) + + // hair + var/list/valid_hairstyles = M.generate_valid_hairstyles() + var/new_style = input("Please select hair style", "Character Generation", head_organ.h_style) as null|anything in valid_hairstyles + + // if new style selected (not cancel) + if (new_style) + head_organ.h_style = new_style + + var/new_hair = input("Please select hair color.", "Character Generation", rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair)) as null|color + if(new_hair) + head_organ.r_hair = hex2num(copytext(new_hair, 2, 4)) + head_organ.g_hair = hex2num(copytext(new_hair, 4, 6)) + head_organ.b_hair = hex2num(copytext(new_hair, 6, 8)) + + // facial hair + var/list/valid_facial_hairstyles = M.generate_valid_facial_hairstyles() + new_style = input("Please select facial style", "Character Generation", head_organ.f_style) as null|anything in valid_facial_hairstyles + + if(new_style) + head_organ.f_style = new_style + + var/new_facial = input("Please select facial hair color.", "Character Generation", rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial)) as null|color + if(new_facial) + head_organ.r_facial = hex2num(copytext(new_facial, 2, 4)) + head_organ.g_facial = hex2num(copytext(new_facial, 4, 6)) + head_organ.b_facial = hex2num(copytext(new_facial, 6, 8)) + + //Head accessory. + if(head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + var/list/valid_head_accessories = M.generate_valid_head_accessories() + var/new_head_accessory = input("Please select head accessory style", "Character Generation", head_organ.ha_style) as null|anything in valid_head_accessories + if(new_head_accessory) + head_organ.ha_style = new_head_accessory + + var/new_head_accessory_colour = input("Please select head accessory colour.", "Character Generation", rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc)) as null|color + if(new_head_accessory_colour) + head_organ.r_headacc = hex2num(copytext(new_head_accessory_colour, 2, 4)) + head_organ.g_headacc = hex2num(copytext(new_head_accessory_colour, 4, 6)) + head_organ.b_headacc = hex2num(copytext(new_head_accessory_colour, 6, 8)) + + //Body markings. + if(M.species.bodyflags & HAS_MARKINGS) + var/list/valid_markings = M.generate_valid_markings() + var/new_marking = input("Please select marking style", "Character Generation", M.m_style) as null|anything in valid_markings + if(new_marking) + M.m_style = new_marking + + var/new_marking_colour = input("Please select marking colour.", "Character Generation", rgb(M.r_markings, M.g_markings, M.b_markings)) as null|color + if(new_marking_colour) + M.r_markings = hex2num(copytext(new_marking_colour, 2, 4)) + M.g_markings = hex2num(copytext(new_marking_colour, 4, 6)) + M.b_markings = hex2num(copytext(new_marking_colour, 6, 8)) + + //Body accessory. + if(M.species.tail && M.species.bodyflags & HAS_TAIL) + var/list/valid_body_accessories = M.generate_valid_body_accessories() + if(valid_body_accessories.len > 1) //By default valid_body_accessories will always have at the very least a 'none' entry populating the list, even if the user's species is not present in any of the list items. + var/new_body_accessory = input("Please select body accessory style", "Character Generation", M.body_accessory) as null|anything in valid_body_accessories + if(new_body_accessory) + M.body_accessory = body_accessory_by_name[new_body_accessory] + + //Skin tone. + if(M.species.bodyflags & HAS_SKIN_TONE) + var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[M.s_tone]") as null|text + if (!new_tone) + new_tone = 35 + M.s_tone = 35 - max(min(round(text2num(new_tone)), 220), 1) + + //Skin colour. + if(M.species.bodyflags & HAS_SKIN_COLOR) + var/new_body_colour = input("Please select body colour.", "Character Generation", rgb(M.r_skin, M.g_skin, M.b_skin)) as null|color + if(new_body_colour) + M.r_skin = hex2num(copytext(new_body_colour, 2, 4)) + M.g_skin = hex2num(copytext(new_body_colour, 4, 6)) + M.b_skin = hex2num(copytext(new_body_colour, 6, 8)) + + M.force_update_limbs() M.regenerate_icons() - M.check_dna() + M.update_dna() M.visible_message("\blue \The [src] morphs and changes [M.get_visible_gender() == MALE ? "his" : M.get_visible_gender() == FEMALE ? "her" : "their"] appearance!", "\blue You change your appearance!", "\red Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!") diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 699f5ac85aa..d0e8d4c9c85 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -17,6 +17,7 @@ if(!AC) AC = new(src, user) AC.name = "SalonPro Nano-Mirror™" + AC.flags = APPEARANCE_ALL_BODY ui_users[user] = AC AC.ui_interact(user) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 2822fa99933..ce20923369d 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -70,6 +70,57 @@ update_fhair() return 1 +/mob/living/carbon/human/proc/change_head_accessory(var/head_accessory_style) + var/obj/item/organ/external/head/H = get_organ("head") + if(!head_accessory_style) + return + + if(H.ha_style == head_accessory_style) + return + + if(!(head_accessory_style in head_accessory_styles_list)) + return + + H.ha_style = head_accessory_style + + update_head_accessory() + return 1 + +/mob/living/carbon/human/proc/change_markings(var/marking_style) + if(!marking_style) + return + + if(src.m_style == marking_style) + return + + if(!(marking_style in marking_styles_list)) + return + + src.m_style = marking_style + + update_markings() + return 1 + +/mob/living/carbon/human/proc/change_body_accessory(var/body_accessory_style) + var/found + if(!body_accessory_style) + return + + if(src.body_accessory) + if(src.body_accessory.name == body_accessory_style) + return + + for(var/B in body_accessory_by_name) + if(B == body_accessory_style) + src.body_accessory = body_accessory_by_name[body_accessory_style] + found = 1 + + if(!found) + return + + update_tail_layer() + return 1 + /mob/living/carbon/human/proc/reset_hair() reset_head_hair() reset_facial_hair() @@ -131,6 +182,30 @@ update_fhair() return 1 +/mob/living/carbon/human/proc/change_head_accessory_color(var/red, var/green, var/blue) + var/obj/item/organ/external/head/H = get_organ("head") + if(red == H.r_headacc && green == H.g_headacc && blue == H.b_headacc) + return + + H.r_headacc = red + H.g_headacc = green + H.b_headacc = blue + + update_head_accessory() + return 1 + +/mob/living/carbon/human/proc/change_marking_color(var/red, var/green, var/blue) + if(red == r_markings && green == g_markings && blue == b_markings) + return + + r_markings = red + g_markings = green + b_markings = blue + + update_markings() + 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.bodyflags & HAS_SKIN_COLOR)) return @@ -176,9 +251,9 @@ /mob/living/carbon/human/proc/generate_valid_hairstyles() var/list/valid_hairstyles = new() + var/obj/item/organ/external/head/H = get_organ("head") for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] - var/obj/item/organ/external/head/H = organs_by_name["head"] if(gender == MALE && S.gender == FEMALE) continue @@ -210,9 +285,9 @@ /mob/living/carbon/human/proc/generate_valid_facial_hairstyles() var/list/valid_facial_hairstyles = new() + var/obj/item/organ/external/head/H = get_organ("head") for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] - var/obj/item/organ/external/head/H = organs_by_name["head"] if(gender == MALE && S.gender == FEMALE) continue @@ -242,3 +317,47 @@ valid_facial_hairstyles += facialhairstyle return valid_facial_hairstyles + +/mob/living/carbon/human/proc/generate_valid_head_accessories() + var/list/valid_head_accessories = new() + var/obj/item/organ/external/head/H = get_organ("head") + for(var/head_accessory in head_accessory_styles_list) + var/datum/sprite_accessory/S = head_accessory_styles_list[head_accessory] + + if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. + continue + valid_head_accessories += head_accessory + + return valid_head_accessories + +/mob/living/carbon/human/proc/generate_valid_markings() + var/list/valid_markings = new() + var/obj/item/organ/external/head/H = get_organ("head") + for(var/marking in marking_styles_list) + var/datum/sprite_accessory/S = marking_styles_list[marking] + + if(!(species.name in S.species_allowed)) //If the user's head is not of a species the marking style allows, skip it. Otherwise, add it to the list. + continue + if(H.species.flags & ALL_RPARTS) //If the user is a species that can have a robotic head... + var/datum/robolimb/robohead = all_robolimbs[H.model] + if(!(S.models_allowed && (robohead.company in S.models_allowed))) //Make sure they don't get markings incompatible with their head. + continue + valid_markings += marking + + return valid_markings + +/mob/living/carbon/human/proc/generate_valid_body_accessories() + var/list/valid_body_accessories = new() + for(var/B in body_accessory_by_name) + var/datum/body_accessory/A = body_accessory_by_name[B] + if(check_rights(R_ADMIN, 1, src)) + valid_body_accessories = body_accessory_by_name.Copy() + else + if(!istype(A)) + valid_body_accessories += "None" //The only null entry should be the "None" option. + continue + if(!(species.name in A.allowed_species)) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list. + continue + valid_body_accessories += B + + return valid_body_accessories diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 15452598ed5..93797b5bb17 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -1898,22 +1898,22 @@ icon_state = "markings_tiger" /datum/sprite_accessory/body_markings/tigerhead - name = "Tiger Body + Head" + name = "Tiger Body and Head" species_allowed = list("Unathi", "Tajaran", "Vulpkanin") icon_state = "markings_tigerhead" /datum/sprite_accessory/body_markings/tigerheadface_taj - name = "Tajaran Tiger Body + Head + Face" + name = "Tajaran Tiger Body, Head and Face" species_allowed = list("Tajaran") icon_state = "markings_tigerheadface_taj" /datum/sprite_accessory/body_markings/tigerheadface_vulp - name = "Vulpkanin Tiger Body + Head + Face" + name = "Vulpkanin Tiger Body, Head and Face" species_allowed = list("Vulpkanin") icon_state = "markings_tigerheadface_vulp" /datum/sprite_accessory/body_markings/tigerheadface_una - name = "Unathi Tiger Body + Head + Face" + name = "Unathi Tiger Body, Head and Face" species_allowed = list("Unathi") icon_state = "markings_tigerheadface_una" diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 4868bfdc7c5..583b68b3dc6 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -6,6 +6,9 @@ var/list/valid_species = list() var/list/valid_hairstyles = list() var/list/valid_facial_hairstyles = list() + var/list/valid_head_accessories = list() + var/list/valid_marking_styles = list() + var/list/valid_body_accessories = list() var/check_whitelist var/list/whitelist @@ -89,6 +92,41 @@ if(owner.change_eye_color(r_eyes, g_eyes, b_eyes)) update_dna() return 1 + if(href_list["head_accessory"]) + if(can_change_head_accessory() && (href_list["head_accessory"] in valid_head_accessories)) + if(owner.change_head_accessory(href_list["head_accessory"])) + update_dna() + return 1 + if(href_list["head_accessory_color"]) + if(can_change_head_accessory()) + var/new_head_accessory = input("Please select head accessory color.", "Head Accessory Color", rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc)) as color|null + if(new_head_accessory && can_still_topic(state)) + var/r_headacc = hex2num(copytext(new_head_accessory, 2, 4)) + var/g_headacc = hex2num(copytext(new_head_accessory, 4, 6)) + var/b_headacc = hex2num(copytext(new_head_accessory, 6, 8)) + if(owner.change_head_accessory_color(r_headacc, g_headacc, b_headacc)) + update_dna() + return 1 + if(href_list["marking"]) + if(can_change_markings() && (href_list["marking"] in valid_marking_styles)) + if(owner.change_markings(href_list["marking"])) + update_dna() + return 1 + if(href_list["marking_color"]) + if(can_change_markings()) + var/new_markings = input("Please select marking color.", "Marking Color", rgb(owner.r_markings, owner.g_markings, owner.b_markings)) as color|null + if(new_markings && can_still_topic(state)) + var/r_markings = hex2num(copytext(new_markings, 2, 4)) + var/g_markings = hex2num(copytext(new_markings, 4, 6)) + var/b_markings = hex2num(copytext(new_markings, 6, 8)) + if(owner.change_marking_color(r_markings, g_markings, b_markings)) + update_dna() + return 1 + if(href_list["body_accessory"]) + if(can_change_body_accessory() && (href_list["body_accessory"] in valid_body_accessories)) + if(owner.change_body_accessory(href_list["body_accessory"])) + update_dna() + return 1 return 0 @@ -109,6 +147,14 @@ data["change_skin_tone"] = can_change_skin_tone() data["change_skin_color"] = can_change_skin_color() data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR) + data["change_head_accessory"] = can_change_head_accessory() + if(data["change_head_accessory"]) + var/head_accessory_styles[0] + for(var/head_accessory_style in valid_head_accessories) + head_accessory_styles[++head_accessory_styles.len] = list("headaccessorystyle" = head_accessory_style) + data["head_accessory_styles"] = head_accessory_styles + data["head_accessory_style"] = head_organ.ha_style + data["change_hair"] = can_change(APPEARANCE_HAIR) if(data["change_hair"]) var/hair_styles[0] @@ -125,8 +171,29 @@ data["facial_hair_styles"] = facial_hair_styles data["facial_hair_style"] = head_organ.f_style + data["change_markings"] = can_change_markings() + if(data["change_markings"]) + var/marking_styles[0] + for(var/marking_style in valid_marking_styles) + marking_styles[++marking_styles.len] = list("markingstyle" = marking_style) + data["marking_styles"] = marking_styles + data["marking_style"] = owner.m_style + + data["change_body_accessory"] = can_change_body_accessory() + if(data["change_body_accessory"]) + var/body_accessory_styles[0] + for(var/body_accessory_style in valid_body_accessories) + body_accessory_styles[++body_accessory_styles.len] = list("bodyaccessorystyle" = body_accessory_style) + data["body_accessory_styles"] = body_accessory_styles + var/datum/body_accessory/BA + if(owner.body_accessory) + BA = owner.body_accessory.name + data["body_accessory_style"] = BA + + data["change_head_accessory_color"] = can_change_head_accessory() data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) + data["change_marking_color"] = can_change_markings() ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src]", 800, 450, state = state) @@ -147,10 +214,22 @@ /datum/nano_module/appearance_changer/proc/can_change_skin_color() return owner && (flags & APPEARANCE_SKIN) && (owner.species.bodyflags & HAS_SKIN_COLOR) +/datum/nano_module/appearance_changer/proc/can_change_head_accessory() + return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + +/datum/nano_module/appearance_changer/proc/can_change_markings() + return owner && (flags & APPEARANCE_MARKINGS) && (owner.species.bodyflags & HAS_MARKINGS) + +/datum/nano_module/appearance_changer/proc/can_change_body_accessory() + return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.species.bodyflags & HAS_TAIL) + /datum/nano_module/appearance_changer/proc/cut_and_generate_data() // Making the assumption that the available species remain constant + valid_hairstyles.Cut() valid_facial_hairstyles.Cut() - valid_facial_hairstyles.Cut() + valid_head_accessories.Cut() + valid_marking_styles.Cut() + valid_body_accessories.Cut() generate_data() /datum/nano_module/appearance_changer/proc/generate_data() @@ -160,4 +239,10 @@ valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist) if(!valid_hairstyles.len || !valid_facial_hairstyles.len) valid_hairstyles = owner.generate_valid_hairstyles() - valid_facial_hairstyles = owner.generate_valid_facial_hairstyles() \ No newline at end of file + valid_facial_hairstyles = owner.generate_valid_facial_hairstyles() + if(!valid_head_accessories.len) + valid_head_accessories = owner.generate_valid_head_accessories() + if(!valid_marking_styles.len) + valid_marking_styles = owner.generate_valid_markings() + if(!valid_body_accessories.len) + valid_body_accessories = owner.generate_valid_body_accessories() diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl index 19e7fd4759b..886076f21d2 100644 --- a/nano/templates/appearance_changer.tmpl +++ b/nano/templates/appearance_changer.tmpl @@ -23,7 +23,7 @@ {{/if}} -{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_hair_color || data.change_facial_hair_color}} +{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_head_accessory_color || data.change_hair_color || data.change_facial_hair_color || data.change_marking_color}}
Colors: @@ -38,12 +38,31 @@ {{if data.change_skin_color}} {{:helper.link('Change skin color', null, { 'skin_color' : 1})}} {{/if}} + {{if data.change_head_accessory_color}} + {{:helper.link('Change head accessory color', null, { 'head_accessory_color' : 1})}} + {{/if}} {{if data.change_hair_color}} {{:helper.link('Change hair color', null, { 'hair_color' : 1})}} {{/if}} {{if data.change_facial_hair_color}} {{:helper.link('Change facial hair color', null, { 'facial_hair_color' : 1})}} {{/if}} + {{if data.change_marking_color}} + {{:helper.link('Change marking color', null, { 'marking_color' : 1})}} + {{/if}} +
+
+{{/if}} + +{{if data.change_head_accessory}} +
+
+ Head accessory styles: +
+
+ {{for data.head_accessory_styles}} + {{:helper.link(value.headaccessorystyle, null, { 'head_accessory' : value.headaccessorystyle}, null, data.head_accessory_style == value.headaccessorystyle ? 'selected' : null)}} + {{/for}}
{{/if}} @@ -73,3 +92,29 @@ {{/if}} + +{{if data.change_markings}} +
+
+ Marking styles: +
+
+ {{for data.marking_styles}} + {{:helper.link(value.markingstyle, null, { 'marking' : value.markingstyle}, null, data.marking_style == value.markingstyle ? 'selected' : null)}} + {{/for}} +
+
+{{/if}} + +{{if data.change_body_accessory}} +
+
+ Body accessory styles: +
+
+ {{for data.body_accessory_styles}} + {{:helper.link(value.bodyaccessorystyle, null, { 'body_accessory' : value.bodyaccessorystyle}, null, data.body_accessory_style == value.bodyaccessorystyle ? 'selected' : null)}} + {{/for}} +
+
+{{/if}} From b1001910b9b88723f839f13c4313021f0c2bc12d Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Tue, 3 May 2016 19:59:31 -0400 Subject: [PATCH 07/10] Typo. --- code/modules/surgery/organs/organ_internal.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index fd61410bdef..8c80b58519a 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -500,7 +500,7 @@ if(istype(owner, /mob/living/carbon/human)) var/mob/living/carbon/human/H = owner var/obj/item/organ/external/head/head_organ = H.get_organ("head") - if(!(head_organ.h_style == "Very Long Hair" || head_organ.h_style == "Mowhawk")) + if(!(head_organ.h_style == "Very Long Hair" || head_organ.h_style == "Mohawk")) if(prob(10)) head_organ.h_style = "Mohawk" else From a5b32d819d3c29a5bbeab1d193d744c9c971b50b Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Wed, 4 May 2016 02:48:05 -0400 Subject: [PATCH 08/10] Fixes Bugs where Alopecia and Facial Hypertrichosis Wouldn't Update Sprite Correctly --- code/datums/diseases/advance/symptoms/beard.dm | 6 +++--- code/datums/diseases/advance/symptoms/shedding.dm | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm index b773d25cf9a..2ce411367f8 100644 --- a/code/datums/diseases/advance/symptoms/beard.dm +++ b/code/datums/diseases/advance/symptoms/beard.dm @@ -36,15 +36,15 @@ BONUS to_chat(H, "Your chin itches.") if(head_organ.f_style == "Shaved") head_organ.f_style = "Jensen Beard" - H.update_hair() + H.update_fhair() if(3, 4) to_chat(H, "You feel tough.") if(!(head_organ.f_style == "Dwarf Beard") && !(head_organ.f_style == "Very Long Beard") && !(head_organ.f_style == "Full Beard")) head_organ.f_style = "Full Beard" - H.update_hair() + H.update_fhair() else to_chat(H, "You feel manly!") if(!(head_organ.f_style == "Dwarf Beard") && !(head_organ.f_style == "Very Long Beard")) head_organ.f_style = pick("Dwarf Beard", "Very Long Beard") - H.update_hair() + H.update_fhair() return \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm index dd1fc5183a6..e79b87d1d4b 100644 --- a/code/datums/diseases/advance/symptoms/shedding.dm +++ b/code/datums/diseases/advance/symptoms/shedding.dm @@ -46,4 +46,5 @@ BONUS head_organ.f_style = "Shaved" head_organ.h_style = "Bald" H.update_hair() + H.update_fhair() return \ No newline at end of file From 1d0965b1f935b18dd8887c4922b37acb2fff9ac1 Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Tue, 10 May 2016 00:25:42 -0400 Subject: [PATCH 09/10] Back up to date. --- code/modules/reagents/newchem/drugs.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/reagents/newchem/drugs.dm b/code/modules/reagents/newchem/drugs.dm index 127a37593d1..62daeee99a3 100644 --- a/code/modules/reagents/newchem/drugs.dm +++ b/code/modules/reagents/newchem/drugs.dm @@ -337,9 +337,10 @@ var/check = rand(0,100) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(check < 8 && H.h_style != "Very Long Beard") - H.h_style = "Very Long Hair" - H.f_style = "Very Long Beard" + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + if(check < 8 && head_organ.h_style != "Very Long Beard") + head_organ.h_style = "Very Long Hair" + head_organ.f_style = "Very Long Beard" H.update_hair() H.update_fhair() H.visible_message("[H] has a wild look in their eyes!") From e5fae9c078905186cc74eacf33e7420e9d5aac0a Mon Sep 17 00:00:00 2001 From: KasparoVy Date: Tue, 10 May 2016 02:23:41 -0400 Subject: [PATCH 10/10] Small Fix Fixes rare occasions where markings (IPC optics) and head accessories wouldn't reset if you switched species via C.M.A. --- .../mob/living/carbon/human/appearance.dm | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index ce20923369d..52488051f50 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -124,6 +124,11 @@ /mob/living/carbon/human/proc/reset_hair() reset_head_hair() reset_facial_hair() + reset_head_accessory() + if(m_style && m_style != "None") //Resets the markings if they were head markings. + var/datum/sprite_accessory/marking_style = marking_styles_list[m_style] + if(marking_style && marking_style.marking_location == "head") + reset_markings() /mob/living/carbon/human/proc/reset_head_hair() var/obj/item/organ/external/head/H = get_organ("head") @@ -146,6 +151,25 @@ H.f_style = "Shaved" update_fhair() +/mob/living/carbon/human/proc/reset_markings() + var/list/valid_markings = generate_valid_markings() + if(valid_markings.len) + m_style = pick(valid_markings) + else + //this shouldn't happen + m_style = "None" + update_markings() + +/mob/living/carbon/human/proc/reset_head_accessory() + var/obj/item/organ/external/head/H = get_organ("head") + var/list/valid_head_accessories = generate_valid_head_accessories() + if(valid_head_accessories.len) + H.ha_style = pick(valid_head_accessories) + else + //this shouldn't happen + H.ha_style = "None" + update_head_accessory() + /mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue) if(red == r_eyes && green == g_eyes && blue == b_eyes) return