diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 004addb050..aca036c94a 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -77,7 +77,7 @@ client/verb/JoinResponseTeam() new_commando << "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however." // By setting an explicit location the mob cannot wander off and decide change appearance elsewhere - new_commando.change_appearance(APPEARANCE_ALL, new_commando.loc, new_commando) + new_commando.change_appearance(APPEARANCE_ALL, new_commando.loc, new_commando, species_whitelist = list("Human", "Unathi", "Tajara")) return diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 14c70df792..9ee6b25e7b 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -79,7 +79,9 @@ var/list/admin_verbs_admin = list( /client/proc/toggle_antagHUD_restrictions, /client/proc/allow_character_respawn, /* Allows a ghost to respawn */ /client/proc/event_manager_panel, - /client/proc/empty_ai_core_toggle_latejoin + /client/proc/empty_ai_core_toggle_latejoin, + /client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */ + /client/proc/change_human_appearance_self /* Allows the human-based mob itself change its basic appearance */ ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -703,6 +705,9 @@ var/list/admin_verbs_mentor = list( set name = "Rename Silicon" set category = "Admin" + if(!istype(S)) + return + if(holder) var/new_name = trim_strip_input(src, "Enter new name. Leave blank or as is to cancel.", "Enter new silicon name", S.real_name) if(new_name && new_name != S.real_name) @@ -710,6 +715,41 @@ var/list/admin_verbs_mentor = list( S.SetName(new_name) feedback_add_details("admin_verb","RAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/change_human_appearance_admin(mob/living/carbon/human/H in world) + set name = "Change Mob Appearance - Admin" + set desc = "Allows you to change the mob appearance" + set category = "Admin" + + if(!istype(H)) + return + + if(holder) + admin_log_and_message_admins("is altering the appearance of [H].") + H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0) + feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/change_human_appearance_self(mob/living/carbon/human/H in world) + set name = "Change Mob Appearance - Self" + set desc = "Allows the mob to change its appearance" + set category = "Admin" + + if(!istype(H)) + return + + if(!H.client) + usr << "Only mobs with clients can alter their own appearance." + return + + if(holder) + switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel")) + if("Yes") + admin_log_and_message_admins("has allowed [H] to change \his appearance, without whitelisting of races.") + H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0) + if("No") + admin_log_and_message_admins("has allowed [H] to change \his appearance, with whitelisting of races.") + H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1) + feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + //---- bs12 verbs ---- diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 2c7e9bc5a1..4976cba4fb 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -1,19 +1,6 @@ -/mob/living/carbon/human - var/list/valid_species = list() - var/list/valid_hairstyles = list() - var/list/valid_facial_hairstyles = list() - -/mob/living/carbon/human/New() - ..() - -/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src) - var/obj/nano_module/appearance_changer/AC = new(location, src) +/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/obj/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist) AC.flags = flags - - generate_valid_species() - generate_valid_hairstyles() - generate_valid_facial_hairstyles() - AC.ui_interact(user) /mob/living/carbon/human/proc/change_species(var/new_species) @@ -23,7 +10,7 @@ if(species == new_species) return - if(!(new_species in valid_species)) + if(!(new_species in all_species)) return set_species(new_species) @@ -47,7 +34,7 @@ if(h_style == hair_style) return - if(!(hair_style in valid_hairstyles)) + if(!(hair_style in hair_styles_list)) return h_style = hair_style @@ -62,7 +49,7 @@ if(f_style == facial_hair_style) return - if(!(facial_hair_style in valid_facial_hairstyles)) + if(!(facial_hair_style in facial_hair_styles_list)) return f_style = facial_hair_style @@ -71,8 +58,8 @@ return 1 /mob/living/carbon/human/proc/reset_hair() - generate_valid_hairstyles() - generate_valid_facial_hairstyles() + var/list/valid_hairstyles = generate_valid_hairstyles() + var/list/valid_facial_hairstyles = generate_valid_facial_hairstyles() if(valid_hairstyles.len) h_style = pick(valid_hairstyles) @@ -145,21 +132,27 @@ check_dna() dna.ready_dna(src) -/mob/living/carbon/human/proc/generate_valid_species() - valid_species.Cut() +/mob/living/carbon/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list()) + var/list/valid_species = new() for(var/current_species_name in all_species) var/datum/species/current_species = all_species[current_species_name] - if(config.usealienwhitelist && !check_rights(R_ADMIN, 0)) //If we're using the whitelist, make sure to check it! + if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it! if(!(current_species.flags & CAN_JOIN)) continue - else if((current_species.flags & IS_WHITELISTED) && !is_alien_whitelisted(src, current_species_name)) + if(whitelist.len && !(current_species_name in whitelist)) + continue + if(blacklist.len && (current_species_name in blacklist)) + continue + if((current_species.flags & IS_WHITELISTED) && !is_alien_whitelisted(src, current_species_name)) continue valid_species += current_species_name + return valid_species + /mob/living/carbon/human/proc/generate_valid_hairstyles() - valid_hairstyles.Cut() + var/list/valid_hairstyles = new() for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] @@ -174,7 +167,7 @@ return valid_hairstyles /mob/living/carbon/human/proc/generate_valid_facial_hairstyles() - valid_facial_hairstyles.Cut() + var/list/valid_facial_hairstyles = new() for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 77757d256c..a8327066e6 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -1,23 +1,37 @@ /obj/nano_module/appearance_changer name = "Appearance Editor" flags = APPEARANCE_ALL_HAIR - var/mob/living/carbon/human/owner + var/mob/living/carbon/human/owner = null + var/list/valid_species = list() + var/list/valid_hairstyles = list() + var/list/valid_facial_hairstyles = list() -/obj/nano_module/appearance_changer/New(var/location, var/mob/living/carbon/human/H) + var/check_whitelist + var/list/whitelist + var/list/blacklist + +/obj/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()) ..() loc = location owner = H + src.check_whitelist = check_species_whitelist + src.whitelist = species_whitelist + src.blacklist = species_blacklist /obj/nano_module/appearance_changer/Topic(ref, href_list) if(..()) return 1 if(href_list["race"]) - if(can_change(APPEARANCE_RACE)) - return owner.change_species(href_list["race"]) + if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species)) + if(owner.change_species(href_list["race"])) + cut_and_generate_data() + return 1 if(href_list["gender"]) if(can_change(APPEARANCE_GENDER)) - return owner.change_gender(href_list["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 = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null @@ -35,7 +49,7 @@ update_dna() return 1 if(href_list["hair"]) - if(can_change(APPEARANCE_HAIR)) + if(can_change(APPEARANCE_HAIR) && (href_list["hair"] in valid_hairstyles)) if(owner.change_hair(href_list["hair"])) update_dna() return 1 @@ -50,7 +64,7 @@ update_dna() return 1 if(href_list["facial_hair"]) - if(can_change(APPEARANCE_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 @@ -78,6 +92,7 @@ return 0 /obj/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + generate_data(check_whitelist, whitelist, blacklist) var/data[0] data["specimen"] = owner.species.name @@ -85,7 +100,7 @@ data["change_race"] = can_change(APPEARANCE_RACE) if(data["change_race"]) var/species[0] - for(var/specimen in owner.valid_species) + for(var/specimen in valid_species) species[++species.len] = list("specimen" = specimen) data["species"] = species @@ -96,7 +111,7 @@ data["change_hair"] = can_change(APPEARANCE_HAIR) if(data["change_hair"]) var/hair_styles[0] - for(var/hair_style in owner.valid_hairstyles) + 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 @@ -104,7 +119,7 @@ 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 owner.valid_facial_hairstyles) + 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 @@ -133,3 +148,16 @@ /obj/nano_module/appearance_changer/proc/can_still_topic() return CanUseTopic(usr, list(), default_state) == STATUS_INTERACTIVE + +/obj/nano_module/appearance_changer/proc/cut_and_generate_data() + // Making the assumption that the available species remain constant + valid_facial_hairstyles.Cut() + valid_facial_hairstyles.Cut() + generate_data() + +/obj/nano_module/appearance_changer/proc/generate_data() + 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() \ No newline at end of file