From 09af5160018474da97d6838a731538cd141d04ee Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Fri, 19 Apr 2024 19:33:35 -0400 Subject: [PATCH 1/4] install gender malware --- code/__DEFINES/DNA.dm | 20 ++++++------- code/datums/dna.dm | 20 ++++++++----- code/game/machinery/cloning.dm | 15 +++++----- code/game/objects/structures/mirror.dm | 12 +++----- code/modules/admin/create_mob.dm | 2 +- code/modules/client/preferences/gender.dm | 30 +++++++------------ code/modules/client/preferences/species.dm | 2 +- .../mob/living/carbon/human/species.dm | 20 +++++++------ .../living/carbon/human/species_types/IPC.dm | 15 +++++++--- .../carbon/human/species_types/abductors.dm | 2 +- .../carbon/human/species_types/android.dm | 2 +- .../carbon/human/species_types/ethereal.dm | 4 +-- .../carbon/human/species_types/golems.dm | 14 ++++----- .../carbon/human/species_types/plasmamen.dm | 4 +-- .../carbon/human/species_types/polysmorphs.dm | 3 +- .../human/species_types/shadowpeople.dm | 6 ++-- .../carbon/human/species_types/skeletons.dm | 4 +-- .../carbon/human/species_types/snail.dm | 2 +- .../carbon/human/species_types/zombies.dm | 8 ++--- .../mob/living/carbon/human/update_icons.dm | 2 +- .../research/xenobiology/xenobiology.dm | 19 ++++++++---- code/modules/surgery/bodyparts/_bodyparts.dm | 2 +- .../interfaces/PreferencesMenu/MainPage.tsx | 18 ++++++----- .../tgui/interfaces/PreferencesMenu/data.ts | 2 +- .../PreferencesMenu/preferences/gender.ts | 29 +++++++++--------- .../species_types/preternis/preternis.dm | 4 +-- .../carbon/human/species_types/szlachta.dm | 2 +- .../modules/surgery/gender_reassignment.dm | 9 ++++-- 28 files changed, 146 insertions(+), 126 deletions(-) diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 57b924379f28..05338f347020 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -169,24 +169,20 @@ #define NOFLASH 17 /// Use this if you want to change the race's color without the player being able to pick their own color. AKA special color shifting #define DYNCOLORS 18 -/// Forced genders -#define AGENDER 19 -#define FGENDER 20 -#define MGENDER 21 /// Do not draw eyes or eyeless overlay -#define NOEYESPRITES 22 +#define NOEYESPRITES 19 /// Used for determining which wounds are applicable to this species. /// if we have flesh (can suffer slash/piercing/burn wounds, requires they don't have NOBLOOD) -#define HAS_FLESH 23 +#define HAS_FLESH 20 /// if we have bones (can suffer bone wounds) -#define HAS_BONE 24 +#define HAS_BONE 21 /// Can't be husked. -#define NOHUSK 25 +#define NOHUSK 22 /// have no mouth to ingest/eat with -#define NOMOUTH 26 +#define NOMOUTH 23 /// has a tail -#define HAS_TAIL 27 -#define NONANITES 28 +#define HAS_TAIL 24 +#define NONANITES 25 //organ slots #define ORGAN_SLOT_BRAIN "brain" @@ -228,9 +224,11 @@ #define CHROMOSOME_NONE 1 #define CHROMOSOME_USED 2 +#define GENDERS 4 #define G_MALE 1 #define G_FEMALE 2 #define G_PLURAL 3 +#define G_NEUTER 4 // Defines for used in creating "perks" for the species preference pages. /// A key that designates UI icon displayed on the perk. diff --git a/code/datums/dna.dm b/code/datums/dna.dm index bc7d33758e9f..64884ff14bf3 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -161,11 +161,13 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) switch(holder.gender) if(MALE) - L[DNA_GENDER_BLOCK] = construct_block(G_MALE, 3) + L[DNA_GENDER_BLOCK] = construct_block(G_MALE, GENDERS) if(FEMALE) - L[DNA_GENDER_BLOCK] = construct_block(G_FEMALE, 3) + L[DNA_GENDER_BLOCK] = construct_block(G_FEMALE, GENDERS) + if(NEUTER) + L[DNA_GENDER_BLOCK] = construct_block(G_NEUTER, GENDERS) else - L[DNA_GENDER_BLOCK] = construct_block(G_PLURAL, 3) + L[DNA_GENDER_BLOCK] = construct_block(G_PLURAL, GENDERS) if(ishuman(holder)) var/mob/living/carbon/human/H = holder if(!GLOB.hair_styles_list.len) @@ -326,11 +328,13 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(DNA_GENDER_BLOCK) switch(H.gender) if(MALE) - set_uni_identity_block(blocknumber, construct_block(G_MALE, 3)) + set_uni_identity_block(blocknumber, construct_block(G_MALE, GENDERS)) if(FEMALE) - set_uni_identity_block(blocknumber, construct_block(G_FEMALE, 3)) + set_uni_identity_block(blocknumber, construct_block(G_FEMALE, GENDERS)) + if(NEUTER) + set_uni_identity_block(blocknumber, construct_block(G_NEUTER, GENDERS)) else - set_uni_identity_block(blocknumber, construct_block(G_PLURAL, 3)) + set_uni_identity_block(blocknumber, construct_block(G_PLURAL, GENDERS)) if(DNA_FACIAL_HAIR_STYLE_BLOCK) set_uni_identity_block(blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)) if(DNA_HAIR_STYLE_BLOCK) @@ -573,11 +577,13 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(!has_dna()) return - switch(deconstruct_block(get_uni_identity_block(dna.unique_identity, DNA_GENDER_BLOCK), 3)) + switch(deconstruct_block(get_uni_identity_block(dna.unique_identity, DNA_GENDER_BLOCK), GENDERS)) if(G_MALE) gender = MALE if(G_FEMALE) gender = FEMALE + if(G_NEUTER) + gender = NEUTER else gender = PLURAL diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 1025f3e0d5a7..2d480ad6fb72 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -242,13 +242,14 @@ GLOBAL_VAR_INIT(clones, 0) var/mob/M = H.easy_random_mutate(NEGATIVE+MINOR_NEGATIVE) if(ismob(M)) H = M - if((AGENDER || MGENDER || FGENDER) in H.dna.species.species_traits) - if((FGENDER in H.dna.species.species_traits) && (H.gender != FEMALE)) - H.gender = FEMALE - if((MGENDER in H.dna.species.species_traits) && (H.gender != MALE)) - H.gender = MALE - if((AGENDER in H.dna.species.species_traits) && (H.gender != PLURAL)) - H.gender = PLURAL + + var/list/possible_genders = H.dna.species.possible_genders + if(!possible_genders || possible_genders.len < 1) + stack_trace("[H.dna.species.type] has no possible genders!") + H.gender = PLURAL // uh oh + else if(possible_genders.len == 1) + H.gender = possible_genders[1] // some species only have one gender + if(!H.GetComponent(/datum/component/mood) && mood) H.AddComponent(/datum/component/mood) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index dd80d3af2396..08e33d49ad1d 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -180,8 +180,8 @@ . += list(RACE = list("select a new race", choosable_races)) . += list(GENDER = list("Select a new gender", list())) var/datum/species/S = H.dna.species - if(!(AGENDER in S.species_traits) || !(FGENDER in S.species_traits) || !(MGENDER in S.species_traits)) - .[GENDER][2] = list(MALE, FEMALE) + if(S.possible_genders.len > 1) + .[GENDER][2] = S.possible_genders if(!(NOEYESPRITES in S.species_traits)) . += list(EYE_COLOR) if(S.use_skintones) @@ -249,12 +249,8 @@ if(RACE) var/newrace = GLOB.species_list[selection] H.set_species(newrace, icon_update=0) - if(FGENDER in S.species_traits) - H.gender = FEMALE - if(MGENDER in S.species_traits) - H.gender = MALE - if(AGENDER in S.species_traits) - H.gender = PLURAL + if(S.possible_genders.len < 2) + H.gender = S.possible_genders[1] return TRUE if(SKIN_COLOR) H.skin_tone = selection diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index b3fd9046d563..5dd391a2593a 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -11,7 +11,7 @@ user << browse(create_panel_helper(create_mob_html), "window=create_mob;size=425x475") /proc/randomize_human(mob/living/carbon/human/human) - human.gender = pick(MALE, FEMALE) + human.gender = pick(MALE, FEMALE, PLURAL, NEUTER) human.real_name = human.dna?.species.random_name(human.gender) || random_unique_name(human.gender) human.name = human.real_name human.underwear = random_underwear(human.gender) diff --git a/code/modules/client/preferences/gender.dm b/code/modules/client/preferences/gender.dm index 687272854929..7860de17b515 100644 --- a/code/modules/client/preferences/gender.dm +++ b/code/modules/client/preferences/gender.dm @@ -5,31 +5,23 @@ priority = PREFERENCE_PRIORITY_GENDER /datum/preference/choiced/gender/init_possible_values() - return list(MALE, FEMALE, PLURAL) + return list(MALE, FEMALE, PLURAL, NEUTER) /datum/preference/choiced/gender/create_informed_default_value(datum/preferences/preferences) var/datum/species/species_type = preferences.read_preference(/datum/preference/choiced/species) - - if(!initial(species_type.sexes) || (AGENDER in initial(species_type.species_traits))) - return PLURAL - else if(FGENDER in initial(species_type.species_traits)) - return FEMALE - else if(MGENDER in initial(species_type.species_traits)) - return MALE - return pick(list(MALE, FEMALE, PLURAL)) + var/list/possible_genders = initial(species_type.possible_genders) + if(possible_genders.len < 1) + stack_trace("[species_type.type] has no possible genders!") + return list(PLURAL) + + return pick(possible_genders) /datum/preference/choiced/gender/apply_to_human(mob/living/carbon/human/target, value) var/datum/species/S = target.dna.species - if(!S.sexes || (AGENDER in S.species_traits)) - value = PLURAL //disregard gender preferences on this species - - if(S) - if(FGENDER in S.species_traits) - value = FEMALE - else if(MGENDER in S.species_traits) - value = MALE - - target.gender = value + if(!(value in S.possible_genders)) + target.gender = pick(S.possible_genders) + else + target.gender = value diff --git a/code/modules/client/preferences/species.dm b/code/modules/client/preferences/species.dm index f5663c7051c7..494faeff5737 100644 --- a/code/modules/client/preferences/species.dm +++ b/code/modules/client/preferences/species.dm @@ -42,7 +42,7 @@ data[species_id]["lore"] = species.get_species_lore() data[species_id]["icon"] = sanitize_css_class_name(species.name) data[species_id]["use_skintones"] = species.use_skintones - data[species_id]["sexes"] = species.sexes && !((FGENDER in species.species_traits) || (MGENDER in species.species_traits) || (AGENDER in species.species_traits)) + data[species_id]["possible_genders"] = species.possible_genders data[species_id]["enabled_features"] = species.get_features() data[species_id]["perks"] = species.get_species_perks() data[species_id]["diet"] = species.get_species_diet() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index d9d893bff101..85506d4d70b7 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -18,8 +18,6 @@ GLOBAL_LIST_EMPTY(features_by_species) var/plural_form /// if alien colors are disabled, this is the color that will be used by that race var/default_color = "#FFF" - /// whether or not the race has sexual characteristics. at the moment this is only FALSE for skeletons and shadows - var/sexes = TRUE ///A list that contains pixel offsets for various clothing features, if your species is a different shape var/list/offset_features = list(OFFSET_UNIFORM = list(0,0), OFFSET_ID = list(0,0), OFFSET_GLOVES = list(0,0), OFFSET_GLASSES = list(0,0), OFFSET_EARS = list(0,0), OFFSET_SHOES = list(0,0), OFFSET_S_STORE = list(0,0), OFFSET_FACEMASK = list(0,0), OFFSET_HEAD = list(0,0), OFFSET_FACE = list(0,0), OFFSET_BELT = list(0,0), OFFSET_BACK = list(0,0), OFFSET_SUIT = list(0,0), OFFSET_NECK = list(0,0)) @@ -38,6 +36,8 @@ GLOBAL_LIST_EMPTY(features_by_species) var/forced_skintone + /// What genders can this race be? + var/list/possible_genders = list(MALE, PLURAL, FEMALE) /// If your race wants to bleed something other than bog standard blood, change this to reagent id. var/datum/reagent/exotic_blood ///If your race uses a non standard bloodtype (A+, O-, AB-, etc) @@ -432,13 +432,15 @@ GLOBAL_LIST_EMPTY(features_by_species) replacement.Insert(C, TRUE, FALSE) /datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) + // Change the gender to fit with the new species + if(!possible_genders || possible_genders.len < 1) + stack_trace("[type] has no possible genders!") + C.gender = PLURAL // uh oh + else if(possible_genders.len == 1) + C.gender = possible_genders[1] // some species only have one gender + else if(!(C.gender in possible_genders)) + C.gender = pick(possible_genders) // randomized gender // Drop the items the new species can't wear - if((AGENDER in species_traits)) - C.gender = PLURAL - if((FGENDER in species_traits)) - C.gender = FEMALE - if((MGENDER in species_traits)) - C.gender = MALE extra_no_equip = old_species.extra_no_equip.Copy() for(var/slot_id in no_equip) var/obj/item/thing = C.get_item_by_slot(slot_id) @@ -801,7 +803,7 @@ GLOBAL_LIST_EMPTY(features_by_species) if(undershirt) if(HAS_TRAIT(H, TRAIT_SKINNY)) //Check for skinny first standing += wear_skinny_version(undershirt.icon_state, undershirt.icon, BODY_LAYER) - else if(H.dna.species.sexes && H.gender == FEMALE) + else if(H.gender == FEMALE && (FEMALE in possible_genders)) standing += wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER) else standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) diff --git a/code/modules/mob/living/carbon/human/species_types/IPC.dm b/code/modules/mob/living/carbon/human/species_types/IPC.dm index a60451f5fd63..bb89c1283ae8 100644 --- a/code/modules/mob/living/carbon/human/species_types/IPC.dm +++ b/code/modules/mob/living/carbon/human/species_types/IPC.dm @@ -5,8 +5,8 @@ id = "ipc" say_mod = "states" //inherited from a user's real species bubble_icon = BUBBLE_ROBOT // beep boop - sexes = FALSE - species_traits = list(NOTRANSSTING,NOEYESPRITES,NO_DNA_COPY,NOZOMBIE,MUTCOLORS,NOHUSK,AGENDER,NOBLOOD,NO_UNDERWEAR) + possible_genders = list(PLURAL, NEUTER) // A MERE OBJECT + species_traits = list(NOTRANSSTING,NOEYESPRITES,NO_DNA_COPY,NOZOMBIE,MUTCOLORS,NOHUSK,NOBLOOD,NO_UNDERWEAR) inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOBREATH,TRAIT_LIMBATTACHMENT,TRAIT_EASYDISMEMBER,TRAIT_NOCRITDAMAGE,TRAIT_GENELESS,TRAIT_MEDICALIGNORE,TRAIT_NOCLONE,TRAIT_TOXIMMUNE,TRAIT_EASILY_WOUNDED,TRAIT_NODEFIB,TRAIT_POWERHUNGRY) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID mutantbrain = /obj/item/organ/brain/positron @@ -390,8 +390,10 @@ ipc martial arts stuff var/list/initial_mutant_bodyparts var/list/initial_step_sounds var/list/initial_walk_sounds + var/list/initial_genders var/list/blacklisted_species = list(/datum/species/ethereal, /datum/species/moth)//species that really don't work with this system (lizards aren't quite right either, but whatever) var/list/old_features + var/old_gender var/ipc_color var/disguised = FALSE @@ -401,6 +403,7 @@ ipc martial arts stuff initial_mutant_bodyparts = LAZYCOPY(mutant_bodyparts) initial_step_sounds = LAZYCOPY(special_step_sounds) initial_walk_sounds = LAZYCOPY(special_walk_sounds) + initial_genders = LAZYCOPY(possible_genders) ipc_color = sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]") fake_species = new /datum/species/human() //default is human @@ -430,7 +433,10 @@ ipc martial arts stuff disguised = TRUE name = fake_species.name say_mod = fake_species.say_mod - sexes = fake_species.sexes + old_gender = H.gender + possible_genders = fake_species.possible_genders + if(!(H.gender in fake_species.possible_genders)) + H.gender = pick(fake_species.possible_genders) species_traits = LAZYCOPY(initial_species_traits) inherent_traits = LAZYCOPY(initial_inherent_traits) mutant_bodyparts = LAZYCOPY(fake_species.mutant_bodyparts) @@ -461,7 +467,8 @@ ipc martial arts stuff disguised = FALSE name = initial(name) say_mod = initial(say_mod) - sexes = initial(sexes) + H.gender = old_gender + possible_genders = LAZYCOPY(initial_genders) species_traits = LAZYCOPY(initial_species_traits) inherent_traits = LAZYCOPY(initial_inherent_traits) mutant_bodyparts = LAZYCOPY(initial_mutant_bodyparts) diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index 77d8396a5b85..001fd806aaf1 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -2,7 +2,7 @@ name = "Abductor" id = "abductor" say_mod = "gibbers" - sexes = FALSE + possible_genders = list(PLURAL) species_traits = list(NOBLOOD,NOEYESPRITES) inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH,TRAIT_RADIMMUNE,TRAIT_GENELESS) mutanttongue = /obj/item/organ/tongue/abductor diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index f61de46f7d57..40fff960d064 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -3,7 +3,7 @@ id = "android" say_mod = "states" bubble_icon = BUBBLE_ROBOT - sexes = FALSE + possible_genders = list(PLURAL, NEUTER) species_traits = list(NOBLOOD, NOZOMBIE, NOHUSK, NO_DNA_COPY, NOTRANSSTING) inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_COLDBLOODED,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_NOCLONE,TRAIT_TOXIMMUNE,TRAIT_GENELESS,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT,TRAIT_MEDICALIGNORE) inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 7c62e342622a..9b297287e191 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -21,7 +21,7 @@ punchstunthreshold = 11 //Still stuns on max hit, but subsequently lower chance to stun overall attack_type = BURN //burn bish damage_overlay_type = "" //We are too cool for regular damage overlays - species_traits = list(NOEYESPRITES, EYECOLOR, MUTCOLORS, AGENDER, HAIR, FACEHAIR, HAS_FLESH) // i mean i guess they have blood so they can have wounds too + species_traits = list(NOEYESPRITES, EYECOLOR, MUTCOLORS, HAIR, FACEHAIR, HAS_FLESH) // i mean i guess they have blood so they can have wounds too changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT inherent_traits = list(TRAIT_POWERHUNGRY, TRAIT_RADIMMUNE) mutant_bodyparts = list("ethereal_mark") @@ -29,7 +29,7 @@ species_language_holder = /datum/language_holder/ethereal deathsound = 'yogstation/sound/voice/ethereal/deathsound.ogg' screamsound = list('sound/voice/ethereal/ethereal_scream_1.ogg', 'sound/voice/ethereal/ethereal_scream_2.ogg', 'sound/voice/ethereal/ethereal_scream_3.ogg') - sexes = FALSE //no fetish content allowed + possible_genders = list(PLURAL) //no fetish content allowed toxic_food = NONE inert_mutation = RADIANTBURST hair_color = "fixedmutcolor" diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 75f4e7625a5d..aea84b84a4a4 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -15,7 +15,7 @@ no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) nojumpsuit = 1 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC - sexes = 1 + possible_genders = list(MALE, PLURAL, FEMALE) damage_overlay_type = "" meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/golem // To prevent golem subtypes from overwhelming the odds when random species @@ -663,7 +663,7 @@ name = "Runic Golem" id = "runic golem" limbs_id = "cultgolem" - sexes = FALSE + possible_genders = list(PLURAL) info_text = "As a Runic Golem, you possess eldritch powers granted by the Elder Goddess Nar'sie." species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES,NOFLASH) //no mutcolors prefix = "Runic" @@ -736,7 +736,7 @@ attack_verb = "smash" attack_effect = ATTACK_EFFECT_SMASH attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg' - sexes = FALSE + possible_genders = list(PLURAL) speedmod = 0 changesource_flags = MIRROR_BADMIN | WABBAJACK damage_overlay_type = "synth" @@ -786,7 +786,7 @@ name = "Cloth Golem" id = "cloth golem" limbs_id = "clothgolem" - sexes = FALSE + possible_genders = list(PLURAL) info_text = "As a Cloth Golem, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable. \ Being made of cloth, your body is magic resistant and faster than that of other golems, but weaker and less resilient." species_traits = list(NOBLOOD,NO_UNDERWEAR) //no mutcolors, and can burn @@ -1120,7 +1120,7 @@ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES,NOFLASH,HAS_BONE) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID mutanttongue = /obj/item/organ/tongue/bone - sexes = FALSE + possible_genders = list(PLURAL) fixed_mut_color = null inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER,TRAIT_NOHUNGER) info_text = "As a Bone Golem, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice." @@ -1421,7 +1421,7 @@ name = "Ruinous Golem" id = "ruinous golem" limbs_id = "ruingolem" - sexes = FALSE + possible_genders = list(PLURAL) armor = 40 //down from 55 species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES) //no mutcolors or eyesprites speedmod = 1.5 //inbetween gold golem and iron @@ -1459,7 +1459,7 @@ name = "Wax Golem" id = "wax golem" limbs_id = "waxgolem" - sexes = FALSE + possible_genders = list(PLURAL) info_text = "As a Wax Golem, you are made of very resilient wax and wick. \ While you can burn, you take much less burn damage than other golems. You also have the ability to revive after death if you died while on fire." species_traits = list(NOBLOOD,NO_UNDERWEAR, NO_DNA_COPY, NOTRANSSTING, NOEYESPRITES) //no mutcolors or eyesprites diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index bc9cea38e847..d77e4b2dae56 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -3,9 +3,9 @@ plural_form = "Plasmamen" id = "plasmaman" say_mod = "rattles" - sexes = FALSE + possible_genders = list(PLURAL) meat = /obj/item/stack/sheet/mineral/plasma - species_traits = list(NOBLOOD,NOTRANSSTING, HAS_BONE, AGENDER, NOHUSK) + species_traits = list(NOBLOOD,NOTRANSSTING, HAS_BONE, NOHUSK) // plasmemes get hard to wound since they only need a severe bone wound to dismember, but unlike skellies, they can't pop their bones back into place. inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER,TRAIT_ALWAYS_CLEAN,TRAIT_HARDLY_WOUNDED) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID diff --git a/code/modules/mob/living/carbon/human/species_types/polysmorphs.dm b/code/modules/mob/living/carbon/human/species_types/polysmorphs.dm index 235923247025..93fc05fc0888 100644 --- a/code/modules/mob/living/carbon/human/species_types/polysmorphs.dm +++ b/code/modules/mob/living/carbon/human/species_types/polysmorphs.dm @@ -2,7 +2,8 @@ //Human xenopmorph hybrid name = "Polysmorph" id = "polysmorph" - species_traits = list(NOEYESPRITES, FGENDER, MUTCOLORS, NOCOLORCHANGE, DIGITIGRADE, HAS_FLESH, HAS_BONE ,HAS_TAIL) + species_traits = list(NOEYESPRITES, MUTCOLORS, NOCOLORCHANGE, DIGITIGRADE, HAS_FLESH, HAS_BONE, HAS_TAIL) + possible_genders = list(FEMALE) inherent_traits = list(TRAIT_ACIDBLOOD, TRAIT_SKINNY) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID exotic_blood = /datum/reagent/toxin/acid //Hell yeah sulphuric acid blood diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index 8ce5cc1307cb..106d9c64b5dc 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -11,11 +11,11 @@ name = "???" plural_form = "???" id = "shadow" - sexes = FALSE + possible_genders = list(PLURAL) bubble_icon = BUBBLE_DARKSPAWN ignored_by = list(/mob/living/simple_animal/hostile/faithless) meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/shadow - species_traits = list(NOBLOOD,NOEYESPRITES,NOFLASH, AGENDER) + species_traits = list(NOBLOOD,NOEYESPRITES, NOFLASH) inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH,TRAIT_GENELESS,TRAIT_NOHUNGER) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC @@ -155,7 +155,7 @@ name = "Darkspawn" id = "darkspawn" limbs_id = "darkspawn" - sexes = FALSE + possible_genders = list(PLURAL) nojumpsuit = TRUE changesource_flags = MIRROR_BADMIN //never put this in the pride pool because they look super valid and can never be changed off of siemens_coeff = 0 diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index 94937184b1d2..0a2046a9da22 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -3,9 +3,9 @@ name = "Spooky Scary Skeleton" id = "skeleton" say_mod = "rattles" - sexes = FALSE + possible_genders = list(NEUTER) meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton - species_traits = list(NOBLOOD,HAS_BONE, NO_DNA_COPY, NOTRANSSTING, NOHUSK, AGENDER) + species_traits = list(NOBLOOD,HAS_BONE, NO_DNA_COPY, NOTRANSSTING, NOHUSK) inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID mutanttongue = /obj/item/organ/tongue/bone diff --git a/code/modules/mob/living/carbon/human/species_types/snail.dm b/code/modules/mob/living/carbon/human/species_types/snail.dm index ab3c9413c5da..30b98bba68f8 100644 --- a/code/modules/mob/living/carbon/human/species_types/snail.dm +++ b/code/modules/mob/living/carbon/human/species_types/snail.dm @@ -15,7 +15,7 @@ punchdamagehigh = 0.5 //snails are soft and squishy siemens_coeff = 2 //snails are mostly water changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | RACE_SWAP | SLIME_EXTRACT - sexes = FALSE //snails are hermaphrodites + possible_genders = list(PLURAL) //snails are hermaphrodites var/shell_type = /obj/item/storage/backpack/snail/species mutanteyes = /obj/item/organ/eyes/snail diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 4f3a9832fafb..b9c6b383b258 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -5,9 +5,9 @@ name = "High-Functioning Zombie" id = "zombie" say_mod = "moans" - sexes = FALSE + possible_genders = list(NEUTER) meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie - species_traits = list(NOBLOOD,NOZOMBIE,NOTRANSSTING,HAS_FLESH,HAS_BONE, AGENDER) + species_traits = list(NOBLOOD, NOZOMBIE, NOTRANSSTING, HAS_FLESH, HAS_BONE) inherent_traits = list(TRAIT_STABLELIVER, TRAIT_STABLEHEART, TRAIT_RESISTCOLD ,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_EASILY_WOUNDED,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID mutanttongue = /obj/item/organ/tongue/zombie @@ -113,8 +113,8 @@ name = "Human" id = "goofzombies" limbs_id = "zombie" //They look like zombies - sexes = FALSE - species_traits = list(HAS_FLESH, HAS_BONE, AGENDER) + possible_genders = list(PLURAL) + species_traits = list(HAS_FLESH, HAS_BONE) inherent_traits = list(TRAIT_EASILY_WOUNDED) //you have no skin inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID //pretty much just rotting flesh, somehow still "technically" alive meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 5a49418e0598..db7a8f7143fd 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -179,7 +179,7 @@ There are several things that need to be remembered: var/mutable_appearance/uniform_overlay - if(dna && dna.species.sexes) + if(dna && (FEMALE in dna.species.possible_genders)) var/G = (gender == FEMALE) ? "f" : "m" if(G == "f" && uniform.fitted != NO_FEMALE_UNIFORM) uniform_overlay = uniform.build_worn_icon( diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 3f8e9b2dea74..e00aa8f6e29d 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -957,13 +957,22 @@ return if(iscarbon(L)) var/mob/living/carbon/C = L - if(C.dna && !(MGENDER in C.dna.species.species_traits) && !(FGENDER in C.dna.species.species_traits) && !(AGENDER in C.dna.species.species_traits)) - if(C.gender == MALE) + if(C.dna && C.dna.species.possible_genders.len > 1) + if(C.gender == MALE && (FEMALE in C.dna.species.possible_genders)) C.gender = FEMALE - C.visible_message(span_boldnotice("[C] suddenly looks more feminine!"), span_boldwarning("You suddenly feel more feminine!")) - else + else if(C.gender == FEMALE && (MALE in C.dna.species.possible_genders)) C.gender = MALE - C.visible_message(span_boldnotice("[C] suddenly looks more masculine!"), span_boldwarning("You suddenly feel more masculine!")) + else + var/list/temp_genders = C.dna.species.possible_genders + temp_genders.Remove(C.gender) + C.gender = pick(temp_genders) + var/gender_adjective = "different" + switch(C.gender) + if(MALE) + gender_adjective = "more masculine" + if(FEMALE) + gender_adjective = "more feminine" + C.visible_message(span_boldnotice("[C] suddenly looks [gender_adjective]!"), span_boldwarning("You suddenly feel [gender_adjective]!")) C.regenerate_icons() else C.visible_message(span_boldnotice("[C]'s physiology fails to change!"), span_boldwarning("The potion fails to meaningfully effect you!")) diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index add44d04d896..579543f086c6 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -859,7 +859,7 @@ body_gender = H.gender - should_draw_gender = S.sexes + should_draw_gender = (FEMALE in S.possible_genders) use_damage_color = S.use_damage_color if((MUTCOLORS in S.species_traits) || (DYNCOLORS in S.species_traits)) diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/MainPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/MainPage.tsx index a9a4009d947a..e53f1b3ee5c8 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/MainPage.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/MainPage.tsx @@ -6,7 +6,7 @@ import { CharacterPreview } from "./CharacterPreview"; import { RandomizationButton } from "./RandomizationButton"; import { ServerPreferencesFetcher } from "./ServerPreferencesFetcher"; import { MultiNameInput, NameInput } from "./names"; -import { Gender, GENDERS } from "./preferences/gender"; +import { GENDERS } from "./preferences/gender"; import features from "./preferences/features"; import { FeatureChoicedServerData, FeatureValueInput } from "./preferences/features/base"; import { filterMap, sortBy } from "common/collections"; @@ -23,8 +23,9 @@ const CharacterControls = (props: { handleRotate: () => void, handleOpenSpecies: () => void, handleCycleBackground: () => void, - gender: Gender, - setGender: (gender: Gender) => void, + gender: string, + genderList: string[], + setGender: (gender: string) => void, showGender: boolean, }) => { return ( @@ -63,6 +64,7 @@ const CharacterControls = (props: { @@ -180,8 +182,9 @@ const ChoicedSelection = (props: { }; const GenderButton = (props: { - handleSetGender: (gender: Gender) => void, - gender: Gender, + handleSetGender: (gender: string) => void, + gender: string, + genderList: string[], }, context) => { const [genderMenuOpen, setGenderMenuOpen] = useLocalState(context, "genderMenuOpen", false); @@ -192,7 +195,7 @@ const GenderButton = (props: { genderMenuOpen && ( - {[Gender.Male, Gender.Female, Gender.Other].map(gender => { + {props.genderList.map(gender => { return (