diff --git a/SQL/migrate/V005__Body_markings.sql b/SQL/migrate/V005__Body_markings.sql new file mode 100644 index 00000000000..36a2a2ebb77 --- /dev/null +++ b/SQL/migrate/V005__Body_markings.sql @@ -0,0 +1,7 @@ +-- +-- Implemented in PR #2607. +-- Character body marking migration file +-- + +ALTER TABLE `ss13_characters` + ADD `body_markings` TEXT NULL DEFAULT NULL AFTER `organs_robotic`; diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index ad552101331..d1cfe21357e 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -46,6 +46,7 @@ var/global/list/facial_hair_styles_list = list() //stores /datum/sprite_accessor var/global/list/facial_hair_styles_male_list = list() var/global/list/facial_hair_styles_female_list = list() var/global/list/skin_styles_female_list = list() //unused +var/global/list/body_marking_styles_list = list() //Underwear var/global/list/underwear_m = list("White" = "m1", "Grey" = "m2", "Green" = "m3", "Blue" = "m4", "Black" = "m5", "Mankini" = "m6", "None") //Curse whoever made male/female underwear diffrent colours var/global/list/underwear_f = list("Red" = "f1", "White" = "f2", "Yellow" = "f3", "Blue" = "f4", "Black" = "f5", "Thong" = "f6", "Black Sports" = "f7","White Sports" = "f8","None") @@ -117,6 +118,12 @@ var/global/list/cloaking_devices = list() else facial_hair_styles_male_list += H.name facial_hair_styles_female_list += H.name + + //Body markings + paths = subtypesof(/datum/sprite_accessory/marking) + for(var/path in paths) + var/datum/sprite_accessory/marking/M = new path() + body_marking_styles_list[M.name] = M //Surgery Steps - Initialize all /datum/surgery_step into a list paths = subtypesof(/datum/surgery_step) diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index e30de18f4e2..421da3b6b60 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -84,6 +84,7 @@ var/global/list/datum/dna/gene/dna_genes[0] // New stuff var/species = "Human" + var/list/body_markings = list() // Make a copy of this strand. // USE THIS WHEN COPYING STUFF OR YOU'LL GET CORRUPTION! @@ -93,6 +94,7 @@ var/global/list/datum/dna/gene/dna_genes[0] new_dna.b_type=b_type new_dna.real_name=real_name new_dna.species=species + new_dna.body_markings=body_markings.Copy() for(var/b=1;b<=DNA_SE_LENGTH;b++) new_dna.SE[b]=SE[b] if(b<=DNA_UI_LENGTH) @@ -152,6 +154,11 @@ var/global/list/datum/dna/gene/dna_genes[0] SetUIValueRange(DNA_UI_HAIR_STYLE, hair, hair_styles_list.len, 1) SetUIValueRange(DNA_UI_BEARD_STYLE, beard, facial_hair_styles_list.len,1) + body_markings.Cut() + for(var/obj/item/organ/external/E in character.organs) + if(E.markings.len) + body_markings[E.limb_name] = E.markings.Copy() + UpdateUI() // Set a DNA UI block's raw value. diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 19b32fef2ea..cee13661d66 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -163,6 +163,13 @@ else H.gender = MALE + //Body markings + for(var/tag in dna.body_markings) + var/obj/item/organ/external/E = H.organs_by_name[tag] + if(E) + var/list/marklist = dna.body_markings[tag] + E.markings = marklist.Copy() + //Hair var/hair = dna.GetUIValueRange(DNA_UI_HAIR_STYLE,hair_styles_list.len) if((0 < hair) && (hair <= hair_styles_list.len)) diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 33ad44ecfa1..caa084cf61e 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -25,6 +25,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O S["disabilities"] >> pref.disabilities S["organ_data"] >> pref.organ_data S["rlimb_data"] >> pref.rlimb_data + S["body_markings"] >> pref.body_markings /datum/category_item/player_setup_item/general/body/save_character(var/savefile/S) S["species"] << pref.species @@ -47,6 +48,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O S["disabilities"] << pref.disabilities S["organ_data"] << pref.organ_data S["rlimb_data"] << pref.rlimb_data + S["body_markings"] << pref.body_markings /datum/category_item/player_setup_item/general/body/gather_load_query() return list("ss13_characters" = list("vars" = list("species", @@ -60,7 +62,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O "b_type", "disabilities", "organs_data" = "organ_data", - "organs_robotic" = "rlimb_data"), + "organs_robotic" = "rlimb_data", + "body_markings"), "args" = list("id"))) /datum/category_item/player_setup_item/general/body/gather_load_parameters() @@ -79,6 +82,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O "disabilities", "organs_data", "organs_robotic", + "body_markings", "id" = 1, "ckey" = 1)) @@ -95,6 +99,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O "disabilities" = pref.disabilities, "organs_data" = list2params(pref.organ_data), "organs_robotic"= list2params(pref.rlimb_data), + "body_markings" = json_encode(pref.body_markings), "id" = pref.current_character, "ckey" = pref.client.ckey) @@ -131,6 +136,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.organ_data = params2list(pref.organ_data) if (pref.rlimb_data) pref.rlimb_data = params2list(pref.rlimb_data) + if (pref.body_markings) + pref.body_markings = json_decode(pref.body_markings) pref.r_hair = sanitize_integer(pref.r_hair, 0, 255, initial(pref.r_hair)) pref.g_hair = sanitize_integer(pref.g_hair, 0, 255, initial(pref.g_hair)) @@ -154,6 +161,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.organ_data = list() if (!pref.rlimb_data || !islist(pref.rlimb_data)) pref.rlimb_data = list() + if (!pref.body_markings || !islist(pref.body_markings)) + pref.body_markings = list() /datum/category_item/player_setup_item/general/body/content(var/mob/user) pref.update_preview_icon() @@ -269,6 +278,12 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O . += "
Body Color
" . += "Change Color
__

" + . += "
Body Markings +
" + for(var/M in pref.body_markings) + . += "[M] - Color" + . += "
__
" + . += "
" + /datum/category_item/player_setup_item/general/body/proc/has_flag(var/datum/species/mob_species, var/flag) return mob_species && (mob_species.appearance_flags & flag) @@ -350,6 +365,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.organ_data.Cut() pref.rlimb_data.Cut() + pref.body_markings.Cut() return TOPIC_REFRESH @@ -437,6 +453,32 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.f_style = new_f_style return TOPIC_REFRESH + else if(href_list["marking_style"]) + var/list/usable_markings = pref.body_markings.Copy() ^ body_marking_styles_list.Copy() + for(var/M in usable_markings) + var/datum/sprite_accessory/S = usable_markings[M] + if(!S.species_allowed.len) + continue + else if(!(pref.species in S.species_allowed)) + usable_markings -= M + + var/new_marking = input(user, "Choose a body marking:", "Character Preference") as null|anything in usable_markings + if(new_marking && CanUseTopic(user)) + pref.body_markings[new_marking] = "#000000" //New markings start black + return TOPIC_REFRESH + + else if(href_list["marking_remove"]) + var/M = href_list["marking_remove"] + pref.body_markings -= M + return TOPIC_REFRESH + + else if(href_list["marking_color"]) + var/M = href_list["marking_color"] + var/mark_color = input(user, "Choose the [M] color: ", "Character Preference", pref.body_markings[M]) as color|null + if(mark_color && CanUseTopic(user)) + pref.body_markings[M] = "[mark_color]" + return TOPIC_REFRESH + else if(href_list["limbs"]) var/list/acceptable_organ_input = list("Left Leg","Right Leg","Left Arm","Right Arm","Left Foot","Right Foot","Left Hand","Right Hand") var/limb_name = input(user, "Which limb do you want to change?") as null|anything in acceptable_organ_input diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 1e3369e1149..5592e4b343c 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -104,6 +104,7 @@ datum/preferences // will probably not be able to do this for head and torso ;) var/list/organ_data = list() var/list/rlimb_data = list() + var/list/body_markings = list() // "name" = "#rgbcolor" var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor" var/list/flavor_texts = list() @@ -388,6 +389,19 @@ datum/preferences else if(status == "mechanical") I.robotize() + for(var/N in character.organs_by_name) + var/obj/item/organ/external/O = character.organs_by_name[N] + O.markings.Cut() + + for(var/M in body_markings) + var/datum/sprite_accessory/marking/mark_datum = body_marking_styles_list[M] + var/mark_color = "[body_markings[M]]" + + for(var/BP in mark_datum.body_parts) + var/obj/item/organ/external/O = character.organs_by_name[BP] + if(O) + O.markings[M] = list("color" = mark_color, "datum" = mark_datum) + character.underwear = underwear character.undershirt = undershirt @@ -545,6 +559,7 @@ datum/preferences organ_data = list() rlimb_data = list() + body_markings = list() player_alt_titles = new() flavor_texts = list() diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 27ca3bd7874..1744f5f453f 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -972,3 +972,132 @@ icon_state = "default" icon = 'icons/mob/human_races/r_skrell.dmi' species_allowed = list("Skrell") + +/* +//////////////////////////// +/ =--------------------= / +/ == Body Markings == / +/ =--------------------= / +//////////////////////////// +*/ +/datum/sprite_accessory/marking + icon = 'icons/mob/human_races/markings.dmi' + do_colouration = 1 //Almost all of them have it, COLOR_ADD + + species_allowed = list() + + var/body_parts = list() //A list of bodyparts this covers, TODO: port defines for organs someday + + tiger_stripes + name = "Tiger Stripes (Tajara)" + icon_state = "tiger" + body_parts = list("l_foot","r_foot","l_leg","r_leg","l_arm","r_arm","chest","groin") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + taj_paw_socks + name = "Socks Coloration (Tajara)" + icon_state = "taj_pawsocks" + body_parts = list("l_foot","r_foot","l_leg","r_leg","l_arm","r_arm","l_hand","r_hand") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + una_paw_socks + name = "Socks Coloration (Unathi)" + icon_state = "una_pawsocks" + body_parts = list("l_foot","r_foot","l_leg","r_leg","l_arm","r_arm","l_hand","r_hand") + species_allowed = list("Unathi") + + paw_socks + name = "Socks Coloration (Generic)" + icon_state = "pawsocks" + body_parts = list("l_foot","r_foot","l_leg","r_leg","l_arm","r_arm","l_hand","r_hand") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara", "Unathi") + + paw_socks_belly + name = "Socks,Belly Coloration (Generic)" + icon_state = "pawsocksbelly" + body_parts = list("l_foot","r_foot","l_leg","r_leg","l_arm","r_arm","l_hand","r_hand","groin","chest") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara", "Unathi") + + belly_hands_feet + name = "Hands,Feet,Belly Color (Minor)" + icon_state = "bellyhandsfeetsmall" + body_parts = list("l_foot","r_foot","l_leg","r_leg","l_arm","r_arm","l_hand","r_hand","groin","chest") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara", "Unathi") + + hands_feet_belly_full + name = "Hands,Feet,Belly Color (Major)" + icon_state = "bellyhandsfeet" + body_parts = list("l_foot","r_foot","l_leg","r_leg","l_arm","r_arm","l_hand","r_hand","groin","chest") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara", "Unathi") + + patches + name = "Color Patches" + icon_state = "patches" + body_parts = list("l_foot","r_foot","l_leg","r_leg","l_arm","r_arm","l_hand","r_hand","chest","groin") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + patchesface + name = "Color Patches (Face)" + icon_state = "patchesface" + body_parts = list("head") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + tigerhead + name = "Tiger Stripes (Head, Minor)" + icon_state = "tigerhead" + body_parts = list("head") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + tigerface + name = "Tiger Stripes (Head, Major)" + icon_state = "tigerface" + body_parts = list("head") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + backstripe + name = "Back Stripe" + icon_state = "backstripe" + body_parts = list("chest") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara", "Unathi") + + taj_nose + name = "Nose Color" + icon_state = "taj_nose" + body_parts = list("head") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + taj_muzzle + name = "Muzzle Color" + icon_state = "taj_muzzle" + body_parts = list("head") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + taj_face + name = "Cheeks Color" + icon_state = "taj_face" + body_parts = list("head") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + taj_all + name = "All Tajara Head" + icon_state = "taj_all" + body_parts = list("head") + species_allowed = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara") + + una_face + name = "Face Color" + icon_state = "una_face" + body_parts = list("head") + species_allowed = list("Unathi") + + una_facelow + name = "Face Color Low" + icon_state = "una_facelow" + body_parts = list("head") + species_allowed = list("Unathi") + + una_scutes + name = "Scutes" + icon_state = "una_scutes" + body_parts = list("chest") + species_allowed = list("Unathi") diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 2fc97926547..de404b15d6f 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -58,6 +58,7 @@ var/can_stand var/body_hair var/painted = 0 + var/list/markings = list() // Markings (body_markings) to apply to the icon /obj/item/organ/external/Destroy() if(parent && parent.children) diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 8812db6fb9d..d9d64244a27 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -8,7 +8,7 @@ if(organ.children && organ.children.len) for(var/obj/item/organ/external/child in organ.children) add_overlay(child.mob_icon) - + overlays |= organ.mob_icon /obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human) @@ -39,13 +39,13 @@ /obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human) ..() - var/obj/item/organ/eyes/eyes + var/obj/item/organ/eyes/eyes if (species.vision_organ) eyes = owner.internal_organs_by_name[species.vision_organ] else eyes = owner.internal_organs_by_name["eyes"] - if(eyes) + if(eyes) eyes.update_colour() /obj/item/organ/external/head/removed() @@ -73,6 +73,13 @@ overlays |= lip_icon mob_icon.Blend(lip_icon, ICON_OVERLAY) + for(var/M in markings) + var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] + var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[limb_name]") + mark_s.Blend(markings[M]["color"], ICON_ADD) + overlays |= mark_s //So when it's not on your body, it has icons + mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons + 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.get_bodytype() in facial_hair_style.species_allowed)) @@ -137,6 +144,14 @@ else if(s_col && s_col.len >= 3) mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD) + //Body markings, does not include head, duplicated (sadly) above. + for(var/M in markings) + var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] + var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[limb_name]") + mark_s.Blend(markings[M]["color"], ICON_ADD) + overlays |= mark_s //So when it's not on your body, it has icons + mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons + if(body_hair && islist(h_col) && h_col.len >= 3) var/list/limb_icon_cache = SSicon_cache.limb_icon_cache var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]" diff --git a/html/changelogs/alberky-PR-2607.yml b/html/changelogs/alberky-PR-2607.yml new file mode 100644 index 00000000000..12991ab8ef7 --- /dev/null +++ b/html/changelogs/alberky-PR-2607.yml @@ -0,0 +1,6 @@ +author: Alberyk + +delete-after: True + +changes: + - rscadd: "Added a body marking system, ported from Polaris." diff --git a/icons/mob/human_races/markings.dmi b/icons/mob/human_races/markings.dmi new file mode 100644 index 00000000000..677b63d85c3 Binary files /dev/null and b/icons/mob/human_races/markings.dmi differ