diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 39c3a83995e..9c0d80e5ebd 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -23,6 +23,9 @@ var/global/list/joblist = list() //list of all jobstypes, minus borg and AI var/global/list/turfs = list() //list of all turfs +#define all_genders_define_list list(MALE,FEMALE,PLURAL,NEUTER) +#define all_genders_text_list list("Male","Female","Plural","Neuter") + //Languages/species/whitelist. var/global/list/all_species[0] var/global/list/all_languages[0] diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 0d0f77a957a..4f211b930e5 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -1,3 +1,4 @@ + /hook/startup/proc/createDatacore() data_core = new /datum/datacore() return 1 @@ -186,7 +187,7 @@ G.fields["fingerprint"] = md5(H.dna.uni_identity) G.fields["p_stat"] = "Active" G.fields["m_stat"] = "Stable" - G.fields["sex"] = H.gender + G.fields["sex"] = gender2text(H.gender) G.fields["species"] = H.get_species() G.fields["home_system"] = H.home_system G.fields["citizenship"] = H.citizenship @@ -199,6 +200,7 @@ var/datum/data/record/M = CreateMedicalRecord(H.real_name, id) M.fields["b_type"] = H.b_type M.fields["b_dna"] = H.dna.unique_enzymes + M.fields["id_gender"] = gender2text(H.identifying_gender) if(H.med_record && !jobban_isbanned(H, "Records")) M.fields["notes"] = H.med_record @@ -214,7 +216,8 @@ L.fields["rank"] = H.mind.assigned_role L.fields["age"] = H.age L.fields["fingerprint"] = md5(H.dna.uni_identity) - L.fields["sex"] = H.gender + L.fields["sex"] = gender2text(H.gender) + L.fields["id_gender"] = gender2text(H.identifying_gender) L.fields["b_type"] = H.b_type L.fields["b_dna"] = H.dna.unique_enzymes L.fields["enzymes"] = H.dna.SE // Used in respawning @@ -418,7 +421,7 @@ G.fields["id"] = id G.fields["rank"] = "Unassigned" G.fields["real_rank"] = "Unassigned" - G.fields["sex"] = "Male" + G.fields["sex"] = "Unknown" G.fields["age"] = "Unknown" G.fields["fingerprint"] = "Unknown" G.fields["p_stat"] = "Active" @@ -460,6 +463,7 @@ M.fields["name"] = name M.fields["b_type"] = "AB+" M.fields["b_dna"] = md5(name) + M.fields["id_gender"] = "Unknown" M.fields["mi_dis"] = "None" M.fields["mi_dis_d"] = "No minor disabilities have been declared." M.fields["ma_dis"] = "None" diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 3eee7615b37..904ff188214 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -49,11 +49,11 @@ /obj/machinery/computer/med_data/attack_hand(mob/user as mob) if(..()) return - var/dat + var/dat = list() if (src.temp) - dat = text("[src.temp]

Clear Screen") + dat += text("[src.temp]

Clear Screen") else - dat = text("Confirm Identity: []
", src, (src.scan ? text("[]", src.scan.name) : "----------")) + dat += text("Confirm Identity: []
", src, (src.scan ? text("[]", src.scan.name) : "----------")) if (src.authenticated) switch(src.screen) if(1.0) @@ -85,8 +85,12 @@ if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) dat += "
Name: [active1.fields["name"]] \ ID: [active1.fields["id"]]
\n \ - Sex: [active1.fields["sex"]]
\n \ - Age: [active1.fields["age"]]
\n \ + Sex: [active1.fields["sex"]]
\n" + if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) + dat += "Gender identity: [active2.fields["id_gender"]]
" + else + dat += "Gender identity: Unknown
" + dat += "Age: [active1.fields["age"]]
\n \ Fingerprint: [active1.fields["fingerprint"]]
\n \ Physical Status: [active1.fields["p_stat"]]
\n \ Mental Status: [active1.fields["m_stat"]]
\ @@ -135,6 +139,7 @@ else else dat += text("{Log In}", src) + dat = jointext(dat,null) user << browse(text("Medical Records[]", dat), "window=med_rec") onclose(user, "med_rec") return @@ -249,10 +254,10 @@ src.active1.fields["fingerprint"] = t1 if("sex") if (istype(src.active1, /datum/data/record)) - if (src.active1.fields["sex"] == "Male") - src.active1.fields["sex"] = "Female" - else - src.active1.fields["sex"] = "Male" + src.active1.fields["sex"] = next_in_list(src.active1.fields["sex"], all_genders_text_list) + if("id_gender") + if (istype(src.active2, /datum/data/record)) + src.active2.fields["id_gender"] = next_in_list(src.active2.fields["id_gender"], all_genders_text_list) if("age") if (istype(src.active1, /datum/data/record)) var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as num diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index c9dfe4fc025..d1d2175c091 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -1,3 +1,11 @@ +datum/preferences + var/biological_gender = MALE + var/identifying_gender = MALE + +datum/preferences/proc/set_biological_gender(var/gender) + biological_gender = gender + identifying_gender = gender + /datum/category_item/player_setup_item/general/basic name = "Basic" sort_order = 1 @@ -5,7 +13,8 @@ /datum/category_item/player_setup_item/general/basic/load_character(var/savefile/S) S["real_name"] >> pref.real_name S["name_is_always_random"] >> pref.be_random_name - S["gender"] >> pref.gender + S["gender"] >> pref.biological_gender + S["id_gender"] << pref.identifying_gender S["age"] >> pref.age S["spawnpoint"] >> pref.spawnpoint S["OOC_Notes"] >> pref.metadata @@ -13,7 +22,8 @@ /datum/category_item/player_setup_item/general/basic/save_character(var/savefile/S) S["real_name"] << pref.real_name S["name_is_always_random"] << pref.be_random_name - S["gender"] << pref.gender + S["gender"] << pref.biological_gender + S["id_gender"] << pref.identifying_gender S["age"] << pref.age S["spawnpoint"] << pref.spawnpoint S["OOC_Notes"] << pref.metadata @@ -21,13 +31,14 @@ /datum/category_item/player_setup_item/general/basic/sanitize_character() if(!pref.species) pref.species = "Human" var/datum/species/S = all_species[pref.species ? pref.species : "Human"] - pref.age = sanitize_integer(pref.age, S.min_age, S.max_age, initial(pref.age)) - pref.gender = sanitize_inlist(pref.gender, S.genders, pick(S.genders)) - pref.real_name = sanitize_name(pref.real_name, pref.species) + pref.age = sanitize_integer(pref.age, S.min_age, S.max_age, initial(pref.age)) + pref.biological_gender = sanitize_inlist(pref.biological_gender, S.genders, pick(S.genders)) + pref.identifying_gender = (pref.identifying_gender in all_genders_define_list) ? pref.identifying_gender : pref.biological_gender + pref.real_name = sanitize_name(pref.real_name, pref.species) if(!pref.real_name) - pref.real_name = random_name(pref.gender, pref.species) - pref.spawnpoint = sanitize_inlist(pref.spawnpoint, spawntypes, initial(pref.spawnpoint)) - pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name)) + pref.real_name = random_name(pref.identifying_gender, pref.species) + pref.spawnpoint = sanitize_inlist(pref.spawnpoint, spawntypes, initial(pref.spawnpoint)) + pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name)) /datum/category_item/player_setup_item/general/basic/content() . = "Name: " @@ -35,7 +46,8 @@ . += "(Random Name) " . += "(Always Random Name: [pref.be_random_name ? "Yes" : "No"])" . += "
" - . += "Gender: [gender2text(pref.gender)]
" + . += "Biological Gender: [gender2text(pref.biological_gender)]
" + . += "Gender Identity: [gender2text(pref.identifying_gender)]
" . += "Age: [pref.age]
" . += "Spawn Point: [pref.spawnpoint]
" if(config.allow_Metadata) @@ -55,17 +67,23 @@ return TOPIC_NOACTION else if(href_list["random_name"]) - pref.real_name = random_name(pref.gender, pref.species) + pref.real_name = random_name(pref.identifying_gender, pref.species) return TOPIC_REFRESH else if(href_list["always_random_name"]) pref.be_random_name = !pref.be_random_name return TOPIC_REFRESH - else if(href_list["gender"]) - var/new_gender = input(user, "Choose your character's gender:", "Character Preference", pref.gender) as null|anything in S.genders + else if(href_list["bio_gender"]) + var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", pref.biological_gender) as null|anything in S.genders if(new_gender && CanUseTopic(user)) - pref.gender = new_gender + pref.set_biological_gender(new_gender) + return TOPIC_REFRESH + + else if(href_list["id_gender"]) + var/new_gender = input(user, "Choose your character's identifying gender:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list + if(new_gender && CanUseTopic(user)) + pref.identifying_gender = new_gender return TOPIC_REFRESH else if(href_list["age"]) diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 4087d1468df..17899026a0e 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -191,7 +191,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O return mob_species && (mob_species.appearance_flags & flag) /datum/category_item/player_setup_item/general/body/OnTopic(var/href,var/list/href_list, var/mob/user) - var/mob_species = all_species[pref.species] + var/datum/species/mob_species = all_species[pref.species] if(href_list["random"]) pref.randomize_appearance_for() @@ -220,18 +220,17 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/prev_species = pref.species pref.species = href_list["set_species"] if(prev_species != pref.species) - mob_species = all_species[pref.species] - if(!(pref.gender in mob_species.genders)) - pref.gender = mob_species.genders[1] + if(!(pref.biological_gender in mob_species.genders)) + pref.set_biological_gender(mob_species.genders[1]) //grab one of the valid hair styles for the newly chosen species var/list/valid_hairstyles = list() for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] - if(pref.gender == MALE && S.gender == FEMALE) + if(pref.biological_gender == MALE && S.gender == FEMALE) continue - if(pref.gender == FEMALE && S.gender == MALE) + if(pref.biological_gender == FEMALE && S.gender == MALE) continue if(!(pref.species in S.species_allowed)) continue @@ -247,9 +246,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/list/valid_facialhairstyles = list() for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] - if(pref.gender == MALE && S.gender == FEMALE) + if(pref.biological_gender == MALE && S.gender == FEMALE) continue - if(pref.gender == FEMALE && S.gender == MALE) + if(pref.biological_gender == FEMALE && S.gender == MALE) continue if(!(pref.species in S.species_allowed)) continue @@ -341,9 +340,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/list/valid_facialhairstyles = list() for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] - if(pref.gender == MALE && S.gender == FEMALE) + if(pref.biological_gender == MALE && S.gender == FEMALE) continue - if(pref.gender == FEMALE && S.gender == MALE) + if(pref.biological_gender == FEMALE && S.gender == MALE) continue if(!(pref.species in S.species_allowed)) continue diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index cc339556c30..861649015c4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -25,7 +25,6 @@ datum/preferences //character preferences var/real_name //our character's name var/be_random_name = 0 //whether we are a random name every round - var/gender = MALE //gender of character (well duh) var/age = 30 //age of character var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2). var/b_type = "A+" //blood type (not-chooseable) @@ -119,8 +118,8 @@ datum/preferences /datum/preferences/New(client/C) player_setup = new(src) - gender = pick(MALE, FEMALE) - real_name = random_name(gender,species) + set_biological_gender(pick(MALE, FEMALE)) + real_name = random_name(identifying_gender,species) b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") gear = list() @@ -254,7 +253,7 @@ datum/preferences // Sanitizing rather than saving as someone might still be editing when copy_to occurs. player_setup.sanitize_setup() if(be_random_name) - real_name = random_name(gender,species) + real_name = random_name(identifying_gender,species) if(config.humans_need_surnames) var/firstspace = findtext(real_name, " ") @@ -284,7 +283,8 @@ datum/preferences character.gen_record = gen_record character.exploit_record = exploit_record - character.gender = gender + character.gender = biological_gender + character.identifying_gender = identifying_gender character.age = age character.b_type = b_type diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 235abffef60..ba9f03579de 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -26,7 +26,7 @@ var/msg = "*---------*\nThis is " - var/datum/gender/T = gender_datums[gender] + var/datum/gender/T = gender_datums[get_gender()] if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender T = gender_datums[PLURAL] else diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 2cb4ad5abf0..0a21d4d5bcf 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -91,3 +91,5 @@ mob_bump_flag = HUMAN mob_push_flags = ~HEAVY mob_swap_flags = ~HEAVY + + var/identifying_gender // In case the human identifies as another gender than it's biological diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 5cb11157f12..df8eead14ec 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -55,6 +55,8 @@ sum += H.ear_protection return sum +/mob/living/carbon/human/get_gender() + return identifying_gender ? identifying_gender : gender #undef HUMAN_EATING_NO_ISSUE #undef HUMAN_EATING_NO_MOUTH diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index fa7116c8222..e9c63918c51 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -147,7 +147,7 @@ BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) ) - var/list/genders = list(MALE, FEMALE, PLURAL) + var/list/genders = list(MALE, FEMALE) // Bump vars var/bump_flag = HUMAN // What are we considered to be when bumped? diff --git a/code/modules/mob/living/voice/voice.dm b/code/modules/mob/living/voice/voice.dm index 82bd397ac13..e4eac0f439c 100644 --- a/code/modules/mob/living/voice/voice.dm +++ b/code/modules/mob/living/voice/voice.dm @@ -33,7 +33,7 @@ var/datum/preferences/p = speaker.client.prefs name = p.real_name real_name = name - gender = p.gender + gender = p.identifying_gender for(var/language in p.alternate_languages) add_language(language) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 43f7d80815b..e9aa06068b4 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -127,7 +127,7 @@ observer.alpha = 127 if(client.prefs.be_random_name) - client.prefs.real_name = random_name(client.prefs.gender) + client.prefs.real_name = random_name(client.prefs.identifying_gender) observer.real_name = client.prefs.real_name observer.name = observer.real_name if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed. @@ -493,7 +493,7 @@ /mob/new_player/get_gender() if(!client || !client.prefs) ..() - return client.prefs.gender + return client.prefs.biological_gender /mob/new_player/is_ready() return ready && ..() diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index e57224a3772..ae75216c4eb 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -1,8 +1,8 @@ /datum/preferences //The mob should have a gender you want before running this proc. Will run fine without H /datum/preferences/proc/randomize_appearance_for(var/mob/living/carbon/human/H) - gender = pick(MALE, FEMALE) - var/datum/species/current_species = all_species[species] + var/datum/species/current_species = all_species[species ? species : "Human"] + set_biological_gender(pick(current_species.genders)) if(current_species) if(current_species.flags & HAS_SKIN_TONE) @@ -25,8 +25,8 @@ use_head_species = H.species.get_bodytype() if(use_head_species) - h_style = random_hair_style(gender, species) - f_style = random_facial_hair_style(gender, species) + h_style = random_hair_style(biological_gender, species) + f_style = random_facial_hair_style(biological_gender, species) randomize_hair_color("hair") randomize_hair_color("facial") @@ -202,7 +202,7 @@ qdel(preview_icon) var/g = "m" - if(gender == FEMALE) g = "f" + if(biological_gender == FEMALE) g = "f" var/icon/icobase var/datum/species/current_species = all_species[species] diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 878a85ab554..85927b92001 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -31,6 +31,10 @@ if(owner.change_gender(href_list["gender"])) cut_and_generate_data() return 1 + if(href_list["gender_id"]) + if(can_change(APPEARANCE_GENDER) && (href_list["gender_id"] in all_genders_define_list)) + owner.identifying_gender = href_list["gender_id"] + 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 + 35) as num|null @@ -100,6 +104,7 @@ data["specimen"] = owner.species.name data["gender"] = owner.gender + data["gender_id"] = owner.identifying_gender data["change_race"] = can_change(APPEARANCE_RACE) if(data["change_race"]) var/species[0] @@ -113,6 +118,11 @@ for(var/gender in owner.species.genders) genders[++genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender) data["genders"] = genders + var/id_genders[0] + for(var/gender in all_genders_define_list) + id_genders[++id_genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender) + data["id_genders"] = id_genders + data["change_skin_tone"] = can_change_skin_tone() data["change_skin_color"] = can_change_skin_color() diff --git a/html/changelogs/Yoshax-gendertweak.yml b/html/changelogs/Yoshax-gendertweak.yml new file mode 100644 index 00000000000..fba5c1e929f --- /dev/null +++ b/html/changelogs/Yoshax-gendertweak.yml @@ -0,0 +1,4 @@ +author: Yoshax +delete-after: True +changes: + - tweak"Splits gender into biological gender and gender identity. Biological gender modifies the sprite (for between male and female) and gender identity determines what pronouns show up when examined or suchlike. Both are displayed in medical records and such. " diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl index 3260f7f83fd..1111add5c53 100644 --- a/nano/templates/appearance_changer.tmpl +++ b/nano/templates/appearance_changer.tmpl @@ -14,13 +14,23 @@ {{if data.change_gender}}
- Gender: + Biological Gender:
{{for data.genders}} {{:helper.link(value.gender_name, null, { 'gender' : value.gender_key}, null, data.gender == value.gender_key ? 'selected' : null)}} {{/for}}
+ +
+
+ Gender Identity: +
+
+ {{for data.id_genders}} + {{:helper.link(value.gender_name, null, { 'gender_id' : value.gender_key}, null, data.gender_id == value.gender_key ? 'selected' : null)}} + {{/for}} +
{{/if}}