From 19df15ad211fb37558785532ed83f1f9a14242fc Mon Sep 17 00:00:00 2001 From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Date: Mon, 19 Oct 2020 19:16:20 +0100 Subject: [PATCH] TGUI Mirrors + CMA (#14648) * TGUI Mirrors + CMA * Forgot this * Farie tweaks * Optimisations --- code/game/objects/structures/mirror.dm | 10 +- .../mob/living/carbon/human/appearance.dm | 6 +- code/modules/nano/modules/human_appearance.dm | 354 ----------------- code/modules/tgui/modules/_base.dm | 4 +- .../tgui/modules/appearance_changer.dm | 355 ++++++++++++++++++ nano/templates/appearance_changer.tmpl | 174 --------- paradise.dme | 2 +- .../tgui/interfaces/AppearanceChanger.js | 254 +++++++++++++ tgui/packages/tgui/public/tgui.bundle.js | 6 +- 9 files changed, 623 insertions(+), 542 deletions(-) delete mode 100644 code/modules/nano/modules/human_appearance.dm create mode 100644 code/modules/tgui/modules/appearance_changer.dm delete mode 100644 nano/templates/appearance_changer.tmpl create mode 100644 tgui/packages/tgui/interfaces/AppearanceChanger.js diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index c657e0056e8..2f2894906ee 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -28,13 +28,13 @@ return if(ishuman(user)) - var/datum/nano_module/appearance_changer/AC = ui_users[user] + var/datum/tgui_module/appearance_changer/AC = ui_users[user] if(!AC) AC = new(src, user) - AC.name = "SalonPro Nano-Mirror™" + AC.name = "SalonPro Nano-Mirror" AC.flags = APPEARANCE_ALL_BODY ui_users[user] = AC - AC.ui_interact(user) + AC.tgui_interact(user) /obj/structure/mirror/obj_break(damage_flag, mapload) if(!broken && !(flags & NODECONSTRUCT)) @@ -121,14 +121,14 @@ else race_list += GLOB.whitelisted_species - var/datum/nano_module/appearance_changer/AC = ui_users[user] + var/datum/tgui_module/appearance_changer/AC = ui_users[user] if(!AC) AC = new(src, user) AC.name = "Magic Mirror" AC.flags = APPEARANCE_ALL AC.whitelist = race_list ui_users[user] = AC - AC.ui_interact(user) + AC.tgui_interact(user) if("Voice") var/voice_choice = input(user, "Perhaps...", "Voice effects") as null|anything in list("Comic Sans", "Wingdings", "Swedish", "Chav", "Mute") diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 58c6a39e6c1..ccb0c29a4ca 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -1,7 +1,7 @@ -/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/topic_state/state = GLOB.default_state) - var/datum/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist) +/mob/living/carbon/human/proc/change_appearance(flags = APPEARANCE_ALL_HAIR, datum/location = src, mob/user = src, check_species_whitelist = TRUE, list/species_whitelist = list(), list/species_blacklist = list()) + var/datum/tgui_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist) AC.flags = flags - AC.ui_interact(user, state = state) + AC.tgui_interact(user) /mob/living/carbon/human/proc/change_gender(var/new_gender, var/update_dna = 1) var/obj/item/organ/external/head/H = bodyparts_by_name["head"] diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm deleted file mode 100644 index 485fee0acb8..00000000000 --- a/code/modules/nano/modules/human_appearance.dm +++ /dev/null @@ -1,354 +0,0 @@ -/datum/nano_module/appearance_changer - 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() - var/list/valid_head_accessories = list() - var/list/valid_head_marking_styles = list() - var/list/valid_body_marking_styles = list() - var/list/valid_tail_marking_styles = list() - var/list/valid_body_accessories = list() - var/list/valid_alt_head_styles = list() - - var/check_whitelist - var/list/whitelist - var/list/blacklist - -/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 - -/datum/nano_module/appearance_changer/Topic(ref, href_list, var/nowindow, var/datum/topic_state/state = GLOB.default_state) - if(..()) - return 1 - - if(href_list["race"]) - if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species)) - var/datum/species/S = GLOB.all_species[href_list["race"]] - if(owner.set_species(S.type)) - cut_and_generate_data() - // Species change creates new organs - runtimes ahoy if we forget this - head_organ = owner.get_organ("head") - return 1 - if(href_list["gender"]) - if(can_change(APPEARANCE_GENDER)) - if(owner.change_gender(href_list["gender"])) - cut_and_generate_data() - return 1 - if(href_list["skin_tone"]) - if(can_change_skin_tone()) - var/new_s_tone = null - if(owner.dna.species.bodyflags & HAS_SKIN_TONE) - new_s_tone = input(usr, "Choose your character's skin tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null - if(isnum(new_s_tone) && can_still_topic(state)) - new_s_tone = 35 - max(min(round(new_s_tone), 220),1) - else if(owner.dna.species.bodyflags & HAS_ICON_SKIN_TONE) - var/const/MAX_LINE_ENTRIES = 4 - var/prompt = "Choose your character's skin tone: 1-[owner.dna.species.icon_skin_tones.len]\n(" - for(var/i = 1 to owner.dna.species.icon_skin_tones.len) - if(i > MAX_LINE_ENTRIES && !((i - 1) % MAX_LINE_ENTRIES)) - prompt += "\n" - prompt += "[i] = [owner.dna.species.icon_skin_tones[i]]" - if(i != owner.dna.species.icon_skin_tones.len) - prompt += ", " - prompt += ")" - - new_s_tone = input(usr, prompt, "Skin Tone", owner.s_tone) as num|null - if(isnum(new_s_tone) && can_still_topic(state)) - new_s_tone = max(min(round(new_s_tone), owner.dna.species.icon_skin_tones.len), 1) - - if(new_s_tone) - return owner.change_skin_tone(new_s_tone) - if(href_list["skin_color"]) - if(can_change_skin_color()) - var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", owner.skin_colour) as color|null - if(new_skin && can_still_topic(state) && owner.change_skin_color(new_skin)) - update_dna() - return 1 - if(href_list["hair"]) - if(can_change(APPEARANCE_HAIR) && (href_list["hair"] in valid_hairstyles)) - if(owner.change_hair(href_list["hair"])) - update_dna() - return 1 - if(href_list["hair_color"]) - if(can_change(APPEARANCE_HAIR_COLOR)) - var/new_hair = input("Please select hair color.", "Hair Color", head_organ.hair_colour) as color|null - if(new_hair && can_still_topic(state) && owner.change_hair_color(new_hair)) - update_dna() - return 1 - if(href_list["secondary_hair_color"]) - if(can_change(APPEARANCE_SECONDARY_HAIR_COLOR)) - var/new_hair = input("Please select secondary hair color.", "Secondary Hair Color", head_organ.sec_hair_colour) as color|null - if(new_hair && can_still_topic(state) && owner.change_hair_color(new_hair, 1)) - update_dna() - return 1 - if(href_list["facial_hair"]) - if(can_change(APPEARANCE_FACIAL_HAIR) && (href_list["facial_hair"] in valid_facial_hairstyles)) - if(owner.change_facial_hair(href_list["facial_hair"])) - update_dna() - 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", head_organ.facial_colour) as color|null - if(new_facial && can_still_topic(state) && owner.change_facial_hair_color(new_facial)) - update_dna() - return 1 - if(href_list["secondary_facial_hair_color"]) - if(can_change(APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR)) - var/new_facial = input("Please select secondary facial hair color.", "Secondary Facial Hair Color", head_organ.sec_facial_colour) as color|null - if(new_facial && can_still_topic(state) && owner.change_facial_hair_color(new_facial, 1)) - update_dna() - return 1 - if(href_list["eye_color"]) - if(can_change(APPEARANCE_EYE_COLOR)) - var/obj/item/organ/internal/eyes/eyes_organ = owner.get_int_organ(/obj/item/organ/internal/eyes) - var/new_eyes = input("Please select eye color.", "Eye Color", eyes_organ.eye_colour) as color|null - if(new_eyes && can_still_topic(state) && owner.change_eye_color(new_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", head_organ.headacc_colour) as color|null - if(new_head_accessory && can_still_topic(state) && owner.change_head_accessory_color(new_head_accessory)) - update_dna() - return 1 - if(href_list["head_marking"]) - if(can_change_markings("head") && (href_list["head_marking"] in valid_head_marking_styles)) - if(owner.change_markings(href_list["head_marking"], "head")) - update_dna() - return 1 - if(href_list["head_marking_color"]) - if(can_change_markings("head")) - var/new_markings = input("Please select head marking color.", "Marking Color", owner.m_colours["head"]) as color|null - if(new_markings && can_still_topic(state) && owner.change_marking_color(new_markings, "head")) - update_dna() - return 1 - if(href_list["body_marking"]) - if(can_change_markings("body") && (href_list["body_marking"] in valid_body_marking_styles)) - if(owner.change_markings(href_list["body_marking"], "body")) - update_dna() - return 1 - if(href_list["body_marking_color"]) - if(can_change_markings("body")) - var/new_markings = input("Please select body marking color.", "Marking Color", owner.m_colours["body"]) as color|null - if(new_markings && can_still_topic(state) && owner.change_marking_color(new_markings, "body")) - update_dna() - return 1 - if(href_list["tail_marking"]) - if(can_change_markings("tail") && (href_list["tail_marking"] in valid_tail_marking_styles)) - if(owner.change_markings(href_list["tail_marking"], "tail")) - update_dna() - return 1 - if(href_list["tail_marking_color"]) - if(can_change_markings("tail")) - var/new_markings = input("Please select tail marking color.", "Marking Color", owner.m_colours["tail"]) as color|null - if(new_markings && can_still_topic(state) && owner.change_marking_color(new_markings, "tail")) - 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() - cut_and_generate_data() - return 1 - if(href_list["alt_head"]) - if(can_change_alt_head() && (href_list["alt_head"] in valid_alt_head_styles)) - if(owner.change_alt_head(href_list["alt_head"])) - update_dna() - head_organ = owner.get_organ("head") //Update the head with the new information. - cut_and_generate_data() - return 1 - - return 0 - -/datum/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = GLOB.default_state) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src]", 800, 450, state = state) - ui.open() - ui.set_auto_update(1) - -/datum/nano_module/appearance_changer/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) - generate_data(check_whitelist, whitelist, blacklist) - var/data[0] - - data["specimen"] = owner.dna.species.name - data["gender"] = owner.gender - data["has_gender"] = owner.dna.species.has_gender - data["change_race"] = can_change(APPEARANCE_RACE) - if(data["change_race"]) - var/species[0] - for(var/specimen in valid_species) - species[++species.len] = list("specimen" = specimen) - data["species"] = species - - data["change_gender"] = can_change(APPEARANCE_GENDER) - data["change_skin_tone"] = can_change_skin_tone() - data["change_skin_color"] = can_change_skin_color() - data["change_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 ? head_organ.ha_style : "None") - - data["change_hair"] = can_change(APPEARANCE_HAIR) - if(data["change_hair"]) - var/hair_styles[0] - for(var/hair_style in valid_hairstyles) - hair_styles[++hair_styles.len] = list("hairstyle" = hair_style) - data["hair_styles"] = hair_styles - data["hair_style"] = (head_organ ? head_organ.h_style : "Skinhead") - - data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) - if(data["change_facial_hair"]) - var/facial_hair_styles[0] - 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"] = (head_organ ? head_organ.f_style : "Shaved") - - data["change_head_markings"] = can_change_markings("head") - if(data["change_head_markings"]) - var/m_style = owner.m_styles["head"] - var/head_marking_styles[0] - for(var/head_marking_style in valid_head_marking_styles) - head_marking_styles[++head_marking_styles.len] = list("headmarkingstyle" = head_marking_style) - data["head_marking_styles"] = head_marking_styles - data["head_marking_style"] = m_style - - data["change_body_markings"] = can_change_markings("body") - if(data["change_body_markings"]) - var/m_style = owner.m_styles["body"] - var/body_marking_styles[0] - for(var/body_marking_style in valid_body_marking_styles) - body_marking_styles[++body_marking_styles.len] = list("bodymarkingstyle" = body_marking_style) - data["body_marking_styles"] = body_marking_styles - data["body_marking_style"] = m_style - - data["change_tail_markings"] = can_change_markings("tail") - if(data["change_tail_markings"]) - var/m_style = owner.m_styles["tail"] - var/tail_marking_styles[0] - for(var/tail_marking_style in valid_tail_marking_styles) - tail_marking_styles[++tail_marking_styles.len] = list("tailmarkingstyle" = tail_marking_style) - data["tail_marking_styles"] = tail_marking_styles - data["tail_marking_style"] = 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 - data["body_accessory_style"] = (owner.body_accessory ? owner.body_accessory.name : "None") - - data["change_alt_head"] = can_change_alt_head() - if(data["change_alt_head"]) - var/alt_head_styles[0] - for(var/alt_head_style in valid_alt_head_styles) - alt_head_styles[++alt_head_styles.len] = list("altheadstyle" = alt_head_style) - data["alt_head_styles"] = alt_head_styles - data["alt_head_style"] = head_organ.alt_head - - data["change_head_accessory_color"] = can_change_head_accessory() - data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) - data["change_secondary_hair_color"] = can_change(APPEARANCE_SECONDARY_HAIR_COLOR) - data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) - data["change_secondary_facial_hair_color"] = can_change(APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR) - data["change_head_marking_color"] = can_change_markings("head") - data["change_body_marking_color"] = can_change_markings("body") - data["change_tail_marking_color"] = can_change_markings("tail") - - return data - -/datum/nano_module/appearance_changer/proc/update_dna() - if(owner && (flags & APPEARANCE_UPDATE_DNA)) - owner.update_dna() - -/datum/nano_module/appearance_changer/proc/can_change(var/flag) - return owner && (flags & flag) - -/datum/nano_module/appearance_changer/proc/can_change_skin_tone() - return owner && (flags & APPEARANCE_SKIN) && ((owner.dna.species.bodyflags & HAS_SKIN_TONE) || (owner.dna.species.bodyflags & HAS_ICON_SKIN_TONE)) - -/datum/nano_module/appearance_changer/proc/can_change_skin_color() - return owner && (flags & APPEARANCE_SKIN) && (owner.dna.species.bodyflags & HAS_SKIN_COLOR) - -/datum/nano_module/appearance_changer/proc/can_change_head_accessory() - if(!head_organ) - log_runtime(EXCEPTION("Missing head!"), owner) - return 0 - return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY) - -/datum/nano_module/appearance_changer/proc/can_change_markings(var/location = "body") - var/marking_flag = HAS_BODY_MARKINGS - var/body_flags = owner.dna.species.bodyflags - if(location == "head") - if(!head_organ) - log_debug("Missing head!") - return 0 - body_flags = head_organ.dna.species.bodyflags - marking_flag = HAS_HEAD_MARKINGS - if(location == "body") - marking_flag = HAS_BODY_MARKINGS - if(location == "tail") - marking_flag = HAS_TAIL_MARKINGS - - return owner && (flags & APPEARANCE_MARKINGS) && (body_flags & marking_flag) - -/datum/nano_module/appearance_changer/proc/can_change_body_accessory() - return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.dna.species.bodyflags & HAS_TAIL) - -/datum/nano_module/appearance_changer/proc/can_change_alt_head() - if(!head_organ) - log_debug("Missing head!") - return 0 - return owner && (flags & APPEARANCE_ALT_HEAD) && (head_organ.dna.species.bodyflags & HAS_ALT_HEADS) - -/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_head_accessories.Cut() - valid_head_marking_styles.Cut() - valid_body_marking_styles.Cut() - valid_tail_marking_styles.Cut() - valid_body_accessories.Cut() - valid_alt_head_styles.Cut() - generate_data() - -/datum/nano_module/appearance_changer/proc/generate_data() - if(!owner) - return - if(!valid_species.len) - 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() - if(!valid_head_accessories.len) - valid_head_accessories = owner.generate_valid_head_accessories() - if(!valid_head_marking_styles.len) - valid_head_marking_styles = owner.generate_valid_markings("head") - if(!valid_body_marking_styles.len) - valid_body_marking_styles = owner.generate_valid_markings("body") - if(!valid_tail_marking_styles.len) - valid_tail_marking_styles = owner.generate_valid_markings("tail") - if(!valid_body_accessories.len) - valid_body_accessories = owner.generate_valid_body_accessories() - if(!valid_alt_head_styles.len) - valid_alt_head_styles = owner.generate_valid_alt_heads() diff --git a/code/modules/tgui/modules/_base.dm b/code/modules/tgui/modules/_base.dm index 36be6295710..d74d5d78716 100644 --- a/code/modules/tgui/modules/_base.dm +++ b/code/modules/tgui/modules/_base.dm @@ -10,8 +10,8 @@ Code is pretty much ripped verbatim from nano modules, but with un-needed stuff var/name var/datum/host -/datum/tgui_module/New(var/host) - src.host = host +/datum/tgui_module/New(datum/_host) + host = _host /datum/tgui_module/tgui_host() return host ? host : src diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm new file mode 100644 index 00000000000..64fb538d9f4 --- /dev/null +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -0,0 +1,355 @@ +/datum/tgui_module/appearance_changer + 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() + var/list/valid_head_accessories = list() + var/list/valid_head_marking_styles = list() + var/list/valid_body_marking_styles = list() + var/list/valid_tail_marking_styles = list() + var/list/valid_body_accessories = list() + var/list/valid_alt_head_styles = list() + + var/check_whitelist + var/list/whitelist + var/list/blacklist + +/datum/tgui_module/appearance_changer/New(datum/host, mob/living/carbon/human/H, check_species_whitelist = TRUE, list/species_whitelist = list(), list/species_blacklist = list()) + ..() + owner = H + head_organ = owner.get_organ("head") + check_whitelist = check_species_whitelist + whitelist = species_whitelist + blacklist = species_blacklist + +/datum/tgui_module/appearance_changer/tgui_act(action, list/params) + if(..()) + return + + . = TRUE + + switch(action) + if("race") + if(can_change(APPEARANCE_RACE) && (params["race"] in valid_species)) + var/datum/species/S = GLOB.all_species[params["race"]] + if(owner.set_species(S.type)) + cut_and_generate_data() + // Species change creates new organs - runtimes ahoy if we forget this + head_organ = owner.get_organ("head") + + if("gender") + if(can_change(APPEARANCE_GENDER)) + if(owner.change_gender(params["gender"])) + cut_and_generate_data() + + if("skin_tone") + if(can_change_skin_tone()) + var/new_s_tone = null + if(owner.dna.species.bodyflags & HAS_SKIN_TONE) + new_s_tone = input(usr, "Choose your character's skin tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null + if(isnum(new_s_tone) && (!..())) + new_s_tone = 35 - max(min(round(new_s_tone), 220),1) + else if(owner.dna.species.bodyflags & HAS_ICON_SKIN_TONE) + var/const/MAX_LINE_ENTRIES = 4 + var/prompt = "Choose your character's skin tone: 1-[length(owner.dna.species.icon_skin_tones)]\n(" + for(var/i in 1 to length(owner.dna.species.icon_skin_tones)) + if(i > MAX_LINE_ENTRIES && !((i - 1) % MAX_LINE_ENTRIES)) + prompt += "\n" + prompt += "[i] = [owner.dna.species.icon_skin_tones[i]]" + if(i != length(owner.dna.species.icon_skin_tones)) + prompt += ", " + prompt += ")" + + new_s_tone = input(usr, prompt, "Skin Tone", owner.s_tone) as num|null + if(isnum(new_s_tone) && (!..())) + new_s_tone = max(min(round(new_s_tone), length(owner.dna.species.icon_skin_tones)), 1) + + if(new_s_tone) + owner.change_skin_tone(new_s_tone) + + if("skin_color") + if(can_change_skin_color()) + var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", owner.skin_colour) as color|null + if(new_skin && (!..()) && owner.change_skin_color(new_skin)) + update_dna() + + if("hair") + if(can_change(APPEARANCE_HAIR) && (params["hair"] in valid_hairstyles)) + if(owner.change_hair(params["hair"])) + update_dna() + + if("hair_color") + if(can_change(APPEARANCE_HAIR_COLOR)) + var/new_hair = input("Please select hair color.", "Hair Color", head_organ.hair_colour) as color|null + if(new_hair && (!..()) && owner.change_hair_color(new_hair)) + update_dna() + + if("secondary_hair_color") + if(can_change(APPEARANCE_SECONDARY_HAIR_COLOR)) + var/new_hair = input("Please select secondary hair color.", "Secondary Hair Color", head_organ.sec_hair_colour) as color|null + if(new_hair && (!..()) && owner.change_hair_color(new_hair, 1)) + update_dna() + + if("facial_hair") + if(can_change(APPEARANCE_FACIAL_HAIR) && (params["facial_hair"] in valid_facial_hairstyles)) + if(owner.change_facial_hair(params["facial_hair"])) + update_dna() + + if("facial_hair_color") + if(can_change(APPEARANCE_FACIAL_HAIR_COLOR)) + var/new_facial = input("Please select facial hair color.", "Facial Hair Color", head_organ.facial_colour) as color|null + if(new_facial && (!..()) && owner.change_facial_hair_color(new_facial)) + update_dna() + + if("secondary_facial_hair_color") + if(can_change(APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR)) + var/new_facial = input("Please select secondary facial hair color.", "Secondary Facial Hair Color", head_organ.sec_facial_colour) as color|null + if(new_facial && (!..()) && owner.change_facial_hair_color(new_facial, 1)) + update_dna() + + if("eye_color") + if(can_change(APPEARANCE_EYE_COLOR)) + var/obj/item/organ/internal/eyes/eyes_organ = owner.get_int_organ(/obj/item/organ/internal/eyes) + var/new_eyes = input("Please select eye color.", "Eye Color", eyes_organ.eye_colour) as color|null + if(new_eyes && (!..()) && owner.change_eye_color(new_eyes)) + update_dna() + + if("head_accessory") + if(can_change_head_accessory() && (params["head_accessory"] in valid_head_accessories)) + if(owner.change_head_accessory(params["head_accessory"])) + update_dna() + + if("head_accessory_color") + if(can_change_head_accessory()) + var/new_head_accessory = input("Please select head accessory color.", "Head Accessory Color", head_organ.headacc_colour) as color|null + if(new_head_accessory && (!..()) && owner.change_head_accessory_color(new_head_accessory)) + update_dna() + + if("head_marking") + if(can_change_markings("head") && (params["head_marking"] in valid_head_marking_styles)) + if(owner.change_markings(params["head_marking"], "head")) + update_dna() + + if("head_marking_color") + if(can_change_markings("head")) + var/new_markings = input("Please select head marking color.", "Marking Color", owner.m_colours["head"]) as color|null + if(new_markings && (!..()) && owner.change_marking_color(new_markings, "head")) + update_dna() + + if("body_marking") + if(can_change_markings("body") && (params["body_marking"] in valid_body_marking_styles)) + if(owner.change_markings(params["body_marking"], "body")) + update_dna() + + if("body_marking_color") + if(can_change_markings("body")) + var/new_markings = input("Please select body marking color.", "Marking Color", owner.m_colours["body"]) as color|null + if(new_markings && (!..()) && owner.change_marking_color(new_markings, "body")) + update_dna() + + if("tail_marking") + if(can_change_markings("tail") && (params["tail_marking"] in valid_tail_marking_styles)) + if(owner.change_markings(params["tail_marking"], "tail")) + update_dna() + + if("tail_marking_color") + if(can_change_markings("tail")) + var/new_markings = input("Please select tail marking color.", "Marking Color", owner.m_colours["tail"]) as color|null + if(new_markings && (!..()) && owner.change_marking_color(new_markings, "tail")) + update_dna() + + if("body_accessory") + if(can_change_body_accessory() && (params["body_accessory"] in valid_body_accessories)) + if(owner.change_body_accessory(params["body_accessory"])) + update_dna() + cut_and_generate_data() + + if("alt_head") + if(can_change_alt_head() && (params["alt_head"] in valid_alt_head_styles)) + if(owner.change_alt_head(params["alt_head"])) + update_dna() + head_organ = owner.get_organ("head") //Update the head with the new information. + cut_and_generate_data() + + +/datum/tgui_module/appearance_changer/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "AppearanceChanger", name, 800, 450, master_ui, state) + ui.open() + +/datum/tgui_module/appearance_changer/tgui_data(mob/user) + generate_data(check_whitelist, whitelist, blacklist) + var/list/data = list() + + data["specimen"] = owner.dna.species.name + data["gender"] = owner.gender + data["has_gender"] = owner.dna.species.has_gender + data["change_race"] = can_change(APPEARANCE_RACE) + if(data["change_race"]) + var/list/species = list() + for(var/specimen in valid_species) + species += list(list("specimen" = specimen)) + data["species"] = species + + data["change_gender"] = can_change(APPEARANCE_GENDER) + data["change_skin_tone"] = can_change_skin_tone() + data["change_skin_color"] = can_change_skin_color() + data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR) + data["change_head_accessory"] = can_change_head_accessory() + if(data["change_head_accessory"]) + var/list/head_accessory_styles = list() + for(var/head_accessory_style in valid_head_accessories) + head_accessory_styles += list(list("headaccessorystyle" = head_accessory_style)) + data["head_accessory_styles"] = head_accessory_styles + data["head_accessory_style"] = head_organ ? head_organ.ha_style : "None" + + data["change_hair"] = can_change(APPEARANCE_HAIR) + if(data["change_hair"]) + var/list/hair_styles = list() + for(var/hair_style in valid_hairstyles) + hair_styles += list(list("hairstyle" = hair_style)) + data["hair_styles"] = hair_styles + data["hair_style"] = head_organ ? head_organ.h_style : "Skinhead" + + data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) + if(data["change_facial_hair"]) + var/list/facial_hair_styles = list() + for(var/facial_hair_style in valid_facial_hairstyles) + facial_hair_styles += list(list("facialhairstyle" = facial_hair_style)) + data["facial_hair_styles"] = facial_hair_styles + data["facial_hair_style"] = head_organ ? head_organ.f_style : "Shaved" + + data["change_head_markings"] = can_change_markings("head") + if(data["change_head_markings"]) + var/m_style = owner.m_styles["head"] + var/list/head_marking_styles = list() + for(var/head_marking_style in valid_head_marking_styles) + head_marking_styles += list(list("headmarkingstyle" = head_marking_style)) + data["head_marking_styles"] = head_marking_styles + data["head_marking_style"] = m_style + + data["change_body_markings"] = can_change_markings("body") + if(data["change_body_markings"]) + var/m_style = owner.m_styles["body"] + var/list/body_marking_styles = list() + for(var/body_marking_style in valid_body_marking_styles) + body_marking_styles += list(list("bodymarkingstyle" = body_marking_style)) + data["body_marking_styles"] = body_marking_styles + data["body_marking_style"] = m_style + + data["change_tail_markings"] = can_change_markings("tail") + if(data["change_tail_markings"]) + var/m_style = owner.m_styles["tail"] + var/list/tail_marking_styles = list() + for(var/tail_marking_style in valid_tail_marking_styles) + tail_marking_styles += list(list("tailmarkingstyle" = tail_marking_style)) + data["tail_marking_styles"] = tail_marking_styles + data["tail_marking_style"] = m_style + + data["change_body_accessory"] = can_change_body_accessory() + if(data["change_body_accessory"]) + var/list/body_accessory_styles = list() + for(var/body_accessory_style in valid_body_accessories) + body_accessory_styles += list(list("bodyaccessorystyle" = body_accessory_style)) + data["body_accessory_styles"] = body_accessory_styles + data["body_accessory_style"] = owner.body_accessory ? owner.body_accessory.name : "None" + + data["change_alt_head"] = can_change_alt_head() + if(data["change_alt_head"]) + var/list/alt_head_styles = list() + for(var/alt_head_style in valid_alt_head_styles) + alt_head_styles += list(list("altheadstyle" = alt_head_style)) + data["alt_head_styles"] = alt_head_styles + data["alt_head_style"] = head_organ.alt_head + + data["change_head_accessory_color"] = can_change_head_accessory() + data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) + data["change_secondary_hair_color"] = can_change(APPEARANCE_SECONDARY_HAIR_COLOR) + data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) + data["change_secondary_facial_hair_color"] = can_change(APPEARANCE_SECONDARY_FACIAL_HAIR_COLOR) + data["change_head_marking_color"] = can_change_markings("head") + data["change_body_marking_color"] = can_change_markings("body") + data["change_tail_marking_color"] = can_change_markings("tail") + + return data + +/datum/tgui_module/appearance_changer/proc/update_dna() + if(owner && (flags & APPEARANCE_UPDATE_DNA)) + owner.update_dna() + +/datum/tgui_module/appearance_changer/proc/can_change(flag) + return owner && (flags & flag) + +/datum/tgui_module/appearance_changer/proc/can_change_skin_tone() + return owner && (flags & APPEARANCE_SKIN) && ((owner.dna.species.bodyflags & HAS_SKIN_TONE) || (owner.dna.species.bodyflags & HAS_ICON_SKIN_TONE)) + +/datum/tgui_module/appearance_changer/proc/can_change_skin_color() + return owner && (flags & APPEARANCE_SKIN) && (owner.dna.species.bodyflags & HAS_SKIN_COLOR) + +/datum/tgui_module/appearance_changer/proc/can_change_head_accessory() + if(!head_organ) + log_runtime(EXCEPTION("Missing head!"), owner) + return FALSE + return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY) + +/datum/tgui_module/appearance_changer/proc/can_change_markings(location = "body") + var/marking_flag = HAS_BODY_MARKINGS + var/body_flags = owner.dna.species.bodyflags + if(location == "head") + if(!head_organ) + log_debug("Missing head!") + return FALSE + body_flags = head_organ.dna.species.bodyflags + marking_flag = HAS_HEAD_MARKINGS + if(location == "body") + marking_flag = HAS_BODY_MARKINGS + if(location == "tail") + marking_flag = HAS_TAIL_MARKINGS + + return owner && (flags & APPEARANCE_MARKINGS) && (body_flags & marking_flag) + +/datum/tgui_module/appearance_changer/proc/can_change_body_accessory() + return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.dna.species.bodyflags & HAS_TAIL) + +/datum/tgui_module/appearance_changer/proc/can_change_alt_head() + if(!head_organ) + log_debug("Missing head!") + return FALSE + return owner && (flags & APPEARANCE_ALT_HEAD) && (head_organ.dna.species.bodyflags & HAS_ALT_HEADS) + +/datum/tgui_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_head_accessories.Cut() + valid_head_marking_styles.Cut() + valid_body_marking_styles.Cut() + valid_tail_marking_styles.Cut() + valid_body_accessories.Cut() + valid_alt_head_styles.Cut() + generate_data() + +/datum/tgui_module/appearance_changer/proc/generate_data() + if(!owner) + return + if(!length(valid_species)) + valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist) + if(!length(valid_hairstyles) || !length(valid_facial_hairstyles)) + valid_hairstyles = owner.generate_valid_hairstyles() + valid_facial_hairstyles = owner.generate_valid_facial_hairstyles() + if(!length(valid_head_accessories)) + valid_head_accessories = owner.generate_valid_head_accessories() + if(!length(valid_head_marking_styles)) + valid_head_marking_styles = owner.generate_valid_markings("head") + if(!length(valid_body_marking_styles)) + valid_body_marking_styles = owner.generate_valid_markings("body") + if(!length(valid_tail_marking_styles)) + valid_tail_marking_styles = owner.generate_valid_markings("tail") + if(!length(valid_body_accessories)) + valid_body_accessories = owner.generate_valid_body_accessories() + if(!length(valid_alt_head_styles)) + valid_alt_head_styles = owner.generate_valid_alt_heads() diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl deleted file mode 100644 index 5e705b2fe46..00000000000 --- a/nano/templates/appearance_changer.tmpl +++ /dev/null @@ -1,174 +0,0 @@ -{{if data.change_race}} -
-
- Species: -
-
- {{for data.species}} - {{:helper.link(value.specimen, null, { 'race' : value.specimen}, null, data.specimen == value.specimen ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} - -{{if data.change_gender}} -
-
- Gender: -
-
- {{:helper.link('Male', null, { 'gender' : 'male'}, null, data.gender == 'male' ? 'selected' : null)}} - {{:helper.link('Female', null, { 'gender' : 'female'}, null, data.gender == 'female' ? 'selected' : null)}} - {{if !data.has_gender}} - {{:helper.link('Genderless', null, { 'gender' : 'plural'}, null, data.gender == 'plural' ? 'selected' : null)}} - {{/if}} -
-
-{{/if}} - -{{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_head_marking_color || data.change_body_marking_color || data.change_tail_marking_color}} -
-
- Colors: -
-
- {{if data.change_eye_color}} - {{:helper.link('Change eye color', null, { 'eye_color' : 1})}} - {{/if}} - {{if data.change_skin_tone}} - {{:helper.link('Change skin tone', null, { 'skin_tone' : 1})}} - {{/if}} - {{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_secondary_hair_color}} - {{:helper.link('Change secondary hair color', null, { 'secondary_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_secondary_facial_hair_color}} - {{:helper.link('Change secondary facial hair color', null, { 'secondary_facial_hair_color' : 1})}} - {{/if}} - {{if data.change_head_marking_color}} - {{:helper.link('Change head marking color', null, { 'head_marking_color' : 1})}} - {{/if}} - {{if data.change_body_marking_color}} - {{:helper.link('Change body marking color', null, { 'body_marking_color' : 1})}} - {{/if}} - {{if data.change_tail_marking_color}} - {{:helper.link('Change tail marking color', null, { 'tail_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}} - -{{if data.change_hair}} -
-
- Hair styles: -
-
- {{for data.hair_styles}} - {{:helper.link(value.hairstyle, null, { 'hair' : value.hairstyle}, null, data.hair_style == value.hairstyle ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} - -{{if data.change_facial_hair}} -
-
- Facial hair styles: -
-
- {{for data.facial_hair_styles}} - {{:helper.link(value.facialhairstyle, null, { 'facial_hair' : value.facialhairstyle}, null, data.facial_hair_style == value.facialhairstyle ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} - -{{if data.change_head_markings}} -
-
- Head Marking styles: -
-
- {{for data.head_marking_styles}} - {{:helper.link(value.headmarkingstyle, null, { 'head_marking' : value.headmarkingstyle}, null, data.head_marking_style == value.headmarkingstyle ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} - -{{if data.change_body_markings}} -
-
- Body Marking styles: -
-
- {{for data.body_marking_styles}} - {{:helper.link(value.bodymarkingstyle, null, { 'body_marking' : value.bodymarkingstyle}, null, data.body_marking_style == value.bodymarkingstyle ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} - -{{if data.change_tail_markings}} -
-
- Tail Marking styles: -
-
- {{for data.tail_marking_styles}} - {{:helper.link(value.tailmarkingstyle, null, { 'tail_marking' : value.tailmarkingstyle}, null, data.tail_marking_style == value.tailmarkingstyle ? '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}} - -{{if data.change_alt_head}} -
-
- Alternate Heads: -
-
- {{for data.alt_head_styles}} - {{:helper.link(value.altheadstyle, null, { 'alt_head' : value.altheadstyle}, null, data.alt_head_style == value.altheadstyle ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} diff --git a/paradise.dme b/paradise.dme index 8d001f1e0ad..0c2973a5041 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2100,7 +2100,6 @@ #include "code\modules\nano\interaction\physical.dm" #include "code\modules\nano\interaction\self.dm" #include "code\modules\nano\interaction\zlevel.dm" -#include "code\modules\nano\modules\human_appearance.dm" #include "code\modules\nano\modules\nano_module.dm" #include "code\modules\newscaster\datums.dm" #include "code\modules\newscaster\defines.dm" @@ -2440,6 +2439,7 @@ #include "code\modules\tgui\states.dm" #include "code\modules\tgui\tgui.dm" #include "code\modules\tgui\modules\_base.dm" +#include "code\modules\tgui\modules\appearance_changer.dm" #include "code\modules\tgui\modules\atmos_control.dm" #include "code\modules\tgui\modules\crew_monitor.dm" #include "code\modules\tgui\modules\ert_manager.dm" diff --git a/tgui/packages/tgui/interfaces/AppearanceChanger.js b/tgui/packages/tgui/interfaces/AppearanceChanger.js new file mode 100644 index 00000000000..56c318bd774 --- /dev/null +++ b/tgui/packages/tgui/interfaces/AppearanceChanger.js @@ -0,0 +1,254 @@ +import { useBackend } from "../backend"; +import { LabeledList, Button } from "../components"; +import { Window } from "../layouts"; + +export const AppearanceChanger = (props, context) => { + const { act, data } = useBackend(context); + const { + change_race, + species, + specimen, + change_gender, + gender, + has_gender, + change_eye_color, + change_skin_tone, + change_skin_color, + change_head_accessory_color, + change_hair_color, + change_secondary_hair_color, + change_facial_hair_color, + change_secondary_facial_hair_color, + change_head_marking_color, + change_body_marking_color, + change_tail_marking_color, + change_head_accessory, + head_accessory_styles, + head_accessory_style, + change_hair, + hair_styles, + hair_style, + change_facial_hair, + facial_hair_styles, + facial_hair_style, + change_head_markings, + head_marking_styles, + head_marking_style, + change_body_markings, + body_marking_styles, + body_marking_style, + change_tail_markings, + tail_marking_styles, + tail_marking_style, + change_body_accessory, + body_accessory_styles, + body_accessory_style, + change_alt_head, + alt_head_styles, + alt_head_style, + } = data; + + let has_colours = false; + // Yes this if statement is awful, but I would rather do it here than inside the template + if (change_eye_color || change_skin_tone || change_skin_color || change_head_accessory_color || change_hair_color || change_secondary_hair_color || change_facial_hair_color || change_secondary_facial_hair_color || change_head_marking_color || change_body_marking_color || change_tail_marking_color) { + has_colours = true; + } + + return ( + + + + {!!change_race && ( + + {species.map(s => ( +