diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index 1f24828c151..1c180031753 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -56,6 +56,7 @@ var/global/list/facial_hair_styles_female_list = list()
var/global/list/skin_styles_female_list = list() //unused
var/global/list/body_marking_styles_list = list()
var/global/list/chargen_disabilities_list = list()
+var/global/static/list/valid_player_genders = list(MALE, FEMALE, NEUTER)
//Underwear
var/global/list/underwear_m = list("White" = "m1", "Grey" = "m2", "Green" = "m3", "Blue" = "m4", "Black" = "m5", "Mankini" = "m6", "Boxers" = "boxers", "Green and blue boxers" = "boxers_green_and_blue","Loveheart boxers" = "boxers_loveheart","None") //Curse whoever made male/female underwear diffrent colours
diff --git a/code/_helpers/sanitize_values.dm b/code/_helpers/sanitize_values.dm
index ca23a2a7f7b..f3dd6ec1531 100644
--- a/code/_helpers/sanitize_values.dm
+++ b/code/_helpers/sanitize_values.dm
@@ -16,19 +16,10 @@
if(default) return default
if(List && List.len)return List[1]
-
-
//more specialised stuff
-/proc/sanitize_gender(gender,neuter=0,plural=0, default="male")
- switch(gender)
- if(MALE, FEMALE)return gender
- if(NEUTER)
- if(neuter) return gender
- else return default
- if(PLURAL)
- if(plural) return gender
- else return default
- return default
+/proc/sanitize_gender(gender, var/species_name)
+ var/datum/species/S = all_species[species_name]
+ return sanitize_inlist(gender, (valid_player_genders & S.default_genders), pick(S.default_genders))
/proc/sanitize_hexcolor(color, default="#000000")
if(!istext(color)) return default
diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm
index df0ecf2af93..abadf7cd575 100644
--- a/code/modules/client/preference_setup/general/01_basic.dm
+++ b/code/modules/client/preference_setup/general/01_basic.dm
@@ -1,7 +1,6 @@
/datum/category_item/player_setup_item/general/basic
name = "Basic"
sort_order = 1
- var/static/list/valid_player_genders = list(MALE, FEMALE)
/datum/category_item/player_setup_item/general/basic/load_character(var/savefile/S)
S["real_name"] >> pref.real_name
@@ -87,7 +86,7 @@
pref.species = "Human"
pref.age = sanitize_integer(text2num(pref.age), pref.getMinAge(), pref.getMaxAge(), initial(pref.age))
- pref.gender = sanitize_inlist(pref.gender, valid_player_genders, pick(valid_player_genders))
+ pref.gender = sanitize_gender(pref.gender, pref.species)
pref.real_name = sanitize_name(pref.real_name, pref.species)
if(!pref.real_name)
pref.real_name = random_name(pref.gender, pref.species)
@@ -139,7 +138,8 @@
return TOPIC_REFRESH
else if(href_list["gender"])
- pref.gender = next_in_list(pref.gender, valid_player_genders)
+ var/datum/species/S = all_species[pref.species]
+ pref.gender = next_in_list(pref.gender, valid_player_genders & S.default_genders)
var/datum/category_item/player_setup_item/general/equipment/equipment_item = category.items[4]
equipment_item.sanitize_character() // sanitize equipment
diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm
index bd455c267cf..1b269bffd19 100644
--- a/code/modules/client/preference_setup/general/03_body.dm
+++ b/code/modules/client/preference_setup/general/03_body.dm
@@ -354,6 +354,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if(prev_species != pref.species)
mob_species = all_species[pref.species]
+ pref.gender = sanitize_gender(pref.gender, pref.species)
var/bodytype = mob_species.get_bodytype()
//grab one of the valid hair styles for the newly chosen species
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 32ccb8be91e..4d858800ec6 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -186,7 +186,7 @@
var/obj/item/grab/G = new /obj/item/grab(M, src)
if(buckled)
- to_chat(M, "You cannot grab [src], \he is buckled in!")
+ to_chat(M, "You cannot grab [src], \he [gender_datums[gender].is] buckled in!")
if(!G) //the grab will delete itself in New if affecting is anchored
return
M.put_in_active_hand(G)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index c7bbf6b8145..2733dff1a65 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -546,7 +546,7 @@ emp_act
var/obj/item/grab/G = new /obj/item/grab(user, src)
if(buckled)
- to_chat(user, "You cannot grab [src], \he is buckled in!")
+ to_chat(user, "You cannot grab [src], \he [gender_datums[gender].is] buckled in!")
if(!G) //the grab will delete itself in New if affecting is anchored
return
user.put_in_active_hand(G)
diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
index 9eafe86c0ae..d285c135c93 100644
--- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
@@ -7,6 +7,7 @@
language = LANGUAGE_VOX
name_language = LANGUAGE_VOX
num_alternate_languages = 1
+ default_genders = list(NEUTER)
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
rarity_value = 4
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
@@ -82,11 +83,6 @@
H.equip_to_slot_or_del(new /obj/item/storage/box/vox(H.back), slot_in_backpack)
H.internal = H.r_hand
H.internals.icon_state = "internal1"
- H.gender = NEUTER
-
-/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H)
- H.gender = NEUTER
- return ..()
/datum/species/vox/armalis
name = "Vox Armalis"
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 6a761794569..3b416cb5582 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -14,6 +14,7 @@
var/age_min = 17
var/age_max = 85
var/economic_modifier = 0
+ var/list/default_genders = list(MALE, FEMALE)
// Icon/appearance vars.
var/icobase = 'icons/mob/human_races/human/r_human.dmi' // Normal icon set.
@@ -398,6 +399,8 @@
H.dna.SetSEState(MONKEYBLOCK,1)
else
H.dna.SetSEState(MONKEYBLOCK,0)
+ if(!H.client || !H.client.prefs || !H.client.prefs.gender)
+ H.gender = pick(default_genders)
/datum/species/proc/handle_death(var/mob/living/carbon/human/H, var/gibbed = 0) //Handles any species-specific death events (such as dionaea nymph spawns).
return
diff --git a/code/modules/mob/living/carbon/human/species/station/diona/diona.dm b/code/modules/mob/living/carbon/human/species/station/diona/diona.dm
index 5d9d8876908..2c8edcd89cf 100644
--- a/code/modules/mob/living/carbon/human/species/station/diona/diona.dm
+++ b/code/modules/mob/living/carbon/human/species/station/diona/diona.dm
@@ -5,6 +5,7 @@
bodytype = "Diona"
age_min = 1
age_max = 1000
+ default_genders = list(NEUTER)
economic_modifier = 3
icobase = 'icons/mob/human_races/diona/r_diona.dmi'
deform = 'icons/mob/human_races/diona/r_def_plant.dmi'
@@ -148,7 +149,6 @@
H.equip_to_slot_or_del(new /obj/item/device/flashlight/flare(H), slot_r_hand)
/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H)
- H.gender = NEUTER
if (ishuman(H))
return ..()
else//Most of the stuff in the parent function doesnt apply to nymphs
diff --git a/code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm b/code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm
index 94df7f84c21..70ee3c5ac9c 100644
--- a/code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm
+++ b/code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm
@@ -6,7 +6,7 @@
age_min = 1
age_max = 30
economic_modifier = 3
- var/neuter_ipc = TRUE
+ default_genders = list(NEUTER)
blurb = "IPCs are, quite simply, \"Integrated Positronic Chassis.\" In this scenario, 'positronic' implies that the chassis possesses a positronic processing core (or positronic brain), meaning that an IPC must be positronic to be considered an IPC. The Baseline model is more of a category - the long of the short is that they represent all unbound synthetic units. Baseline models cover anything that is not an Industrial chassis or a Shell chassis. They can be custom made or assembly made. The most common feature of the Baseline model is a simple design, skeletal or semi-humanoid, and ordinary atmospheric diffusion cooling systems."
@@ -119,8 +119,6 @@
var/sprint_charge_factor = 0.65
datum/species/machine/handle_post_spawn(var/mob/living/carbon/human/H)
- if (neuter_ipc)
- H.gender = NEUTER
. = ..()
check_tag(H, H.client)
@@ -300,8 +298,6 @@ datum/species/machine/handle_post_spawn(var/mob/living/carbon/human/H)
/datum/species/machine/before_equip(var/mob/living/carbon/human/H)
. = ..()
check_tag(H, H.client)
- if (neuter_ipc)
- H.gender = NEUTER
/datum/species/machine/handle_death_check(var/mob/living/carbon/human/H)
if(H.get_total_health() <= config.health_threshold_dead)
diff --git a/code/modules/mob/living/carbon/human/species/station/ipc/ipc_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/ipc/ipc_subspecies.dm
index 39527739744..02907f8d58c 100644
--- a/code/modules/mob/living/carbon/human/species/station/ipc/ipc_subspecies.dm
+++ b/code/modules/mob/living/carbon/human/species/station/ipc/ipc_subspecies.dm
@@ -4,7 +4,7 @@
short_name = "jak"
name_plural = "Shells"
bodytype = "Human"
- neuter_ipc = FALSE
+ default_genders = list(MALE, FEMALE)
burn_mod = 1.2
grab_mod = 1
diff --git a/code/modules/mob/living/carbon/human/species/station/vaurca/vaurca.dm b/code/modules/mob/living/carbon/human/species/station/vaurca/vaurca.dm
index 70d60d14bc5..a50136b27f2 100644
--- a/code/modules/mob/living/carbon/human/species/station/vaurca/vaurca.dm
+++ b/code/modules/mob/living/carbon/human/species/station/vaurca/vaurca.dm
@@ -5,6 +5,7 @@
bodytype = "Vaurca"
age_min = 1
age_max = 20
+ default_genders = list(NEUTER)
economic_modifier = 2
language = LANGUAGE_VAURCA
primitive_form = "V'krexi"
diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm
index 62d9f4ef720..de7a2ffacd8 100644
--- a/code/modules/mob/living/carbon/human/unarmed_attack.dm
+++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm
@@ -85,7 +85,7 @@ var/global/list/sparring_attack_cache = list()
target.apply_effect(attack_damage * 0.4, WEAKEN, armour)
if(BP_GROIN)
if(pain_message)
- target.visible_message("[target] looks like \he is in pain!", "[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your [pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]")
+ target.visible_message("[target] looks like \he [gender_datums[target.gender].is] in pain!", "[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your [pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]")
target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour)
if(BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT)
if(!target.lying)
diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm
index e5d63ef6978..d0e15ab3de2 100644
--- a/code/modules/mob/living/silicon/pai/software_modules.dm
+++ b/code/modules/mob/living/silicon/pai/software_modules.dm
@@ -74,7 +74,7 @@
else
to_chat(P, "DNA does not match stored Master DNA.")
else
- to_chat(P, "[M] does not seem like \he is going to provide a DNA sample willingly.")
+ to_chat(P, "[M] does not seem like \he [gender_datums[M.gender].is] going to provide a DNA sample willingly.")
return 1
/datum/pai_software/radio_config
diff --git a/html/changelogs/gender_stuff.yml b/html/changelogs/gender_stuff.yml
new file mode 100644
index 00000000000..46a670b5313
--- /dev/null
+++ b/html/changelogs/gender_stuff.yml
@@ -0,0 +1,6 @@
+author: mikomyazaki
+
+delete-after: True
+
+changes:
+ - bugfix: "Species that are gender neutral will now properly spawn with the neuter gender, and be neuter gender in the character setup."
\ No newline at end of file