diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index a5924994e7..cb1896cb1a 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -47,7 +47,7 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list)
return pick(GLOB.socks_list)
-/proc/random_features()
+/proc/random_features(intendedspecies)
if(!GLOB.tails_list_human.len)
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human)
if(!GLOB.tails_list_lizard.len)
@@ -105,6 +105,8 @@
var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[mtpath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
+ continue
if(!S.ckeys_allowed)
snowflake_mam_tails_list[S.name] = mtpath
var/list/snowflake_markings_list = list()
@@ -112,6 +114,8 @@
var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[mmpath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
+ continue
if(!S.ckeys_allowed)
snowflake_markings_list[S.name] = mmpath
var/list/snowflake_ears_list = list()
@@ -119,6 +123,8 @@
var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[mepath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
+ continue
if(!S.ckeys_allowed)
snowflake_ears_list[S.name] = mepath
var/list/snowflake_mam_snouts_list = list()
@@ -126,8 +132,19 @@
var/datum/sprite_accessory/mam_snouts/instance = GLOB.mam_snouts_list[mspath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
+ continue
if(!S.ckeys_allowed)
snowflake_mam_snouts_list[S.name] = mspath
+ var/list/snowflake_ipc_antenna_list = list()
+ for(var/mspath in GLOB.ipc_antennas_list)
+ var/datum/sprite_accessory/mam_snouts/instance = GLOB.ipc_antennas_list[mspath]
+ if(istype(instance, /datum/sprite_accessory))
+ var/datum/sprite_accessory/S = instance
+ if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
+ continue
+ if(!S.ckeys_allowed)
+ snowflake_ipc_antenna_list[S.name] = mspath
var/color1 = random_short_color()
var/color2 = random_short_color()
var/color3 = random_short_color()
@@ -153,10 +170,10 @@
"insect_fluff" = "None",
"insect_markings" = pick(GLOB.insect_markings_list),
"taur" = "None",
- "mam_body_markings" = pick(snowflake_markings_list),
- "mam_ears" = pick(snowflake_ears_list),
- "mam_snouts" = pick(snowflake_mam_snouts_list),
- "mam_tail" = pick(snowflake_mam_tails_list),
+ "mam_body_markings" = snowflake_markings_list.len ? pick(snowflake_markings_list) : "None",
+ "mam_ears" = snowflake_ears_list ? pick(snowflake_ears_list) : "None",
+ "mam_snouts" = snowflake_mam_snouts_list ? pick(snowflake_mam_snouts_list) : "None",
+ "mam_tail" = snowflake_mam_tails_list ? pick(snowflake_mam_tails_list) : "None",
"mam_tail_animated" = "None",
"xenodorsal" = "Standard",
"xenohead" = "Standard",
@@ -204,7 +221,7 @@
"womb_cum_rate" = CUM_RATE,
"womb_cum_mult" = CUM_RATE_MULT,
"womb_efficiency" = CUM_EFFICIENCY,
- "ipc_screen" = "Sunburst",
+ "ipc_screen" = snowflake_ipc_antenna_list ? pick(snowflake_ipc_antenna_list) : "None",
"ipc_antenna" = "None",
"flavor_text" = "",
"meat_type" = "Mammalian"
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 68c6839482..2f4dba9c38 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -218,7 +218,7 @@
unique_enzymes = generate_unique_enzymes()
uni_identity = generate_uni_identity()
struc_enzymes = generate_struc_enzymes()
- features = random_features()
+ features = random_features(species?.id)
/datum/dna/stored //subtype used by brain mob's stored_dna
diff --git a/code/modules/antagonists/bloodsucker/powers/veil.dm b/code/modules/antagonists/bloodsucker/powers/veil.dm
index 0c83cc2d44..0b3cded832 100644
--- a/code/modules/antagonists/bloodsucker/powers/veil.dm
+++ b/code/modules/antagonists/bloodsucker/powers/veil.dm
@@ -92,7 +92,7 @@
H.socks = random_socks(H.gender)
//H.eye_color = random_eye_color()
REMOVE_TRAIT(H, TRAIT_DISFIGURED, null) //
- H.dna.features = random_features()
+ H.dna.features = random_features(H.dna.species?.id)
// Apply Appearance
H.update_body() // Outfit and underware, also body.
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index cdc3fbc5b9..3d4c22d8b6 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -210,6 +210,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/icon/bgstate = "steel"
var/list/bgstate_options = list("000", "midgrey", "FFF", "white", "steel", "techmaint", "dark", "plating", "reinforced")
+ var/show_mismatched_markings = FALSE //determines whether or not the markings lists should show markings that don't match the currently selected species. Intentionally left unsaved.
+
/datum/preferences/New(client/C)
parent = C
@@ -411,6 +413,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//Mutant stuff
var/mutant_category = 0
+ dat += APPEARANCE_CATEGORY_COLUMN
+ dat += "
Show mismatched markings
"
+ dat += "[show_mismatched_markings ? "Yes" : "No"]"
+ mutant_category++
+ if(mutant_category >= MAX_MUTANT_ROWS) //just in case someone sets the max rows to 1 or something dumb like that
+ dat += ""
+ mutant_category = 0
+
if("tail_lizard" in pref_species.default_features)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -1618,6 +1628,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
to_chat(user, "Invalid color. Your color is not bright enough.")
+ if("mismatched_markings")
+ show_mismatched_markings = !show_mismatched_markings
+
if("ipc_screen")
var/new_ipc_screen
new_ipc_screen = input(user, "Choose your character's screen:", "Character Preference") as null|anything in GLOB.ipc_screens_list
@@ -1625,8 +1638,18 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["ipc_screen"] = new_ipc_screen
if("ipc_antenna")
+ var/list/snowflake_antenna_list = list()
+ //Potential todo: turn all of THIS into a define to reduce copypasta.
+ for(var/path in GLOB.ipc_antennas_list)
+ var/datum/sprite_accessory/antenna/instance = GLOB.ipc_antennas_list[path]
+ if(istype(instance, /datum/sprite_accessory))
+ var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
+ if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
+ snowflake_antenna_list[S.name] = path
var/new_ipc_antenna
- new_ipc_antenna = input(user, "Choose your character's antenna:", "Character Preference") as null|anything in GLOB.ipc_antennas_list
+ new_ipc_antenna = input(user, "Choose your character's antenna:", "Character Preference") as null|anything in snowflake_antenna_list
if(new_ipc_antenna)
features["ipc_antenna"] = new_ipc_antenna
@@ -1646,6 +1669,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/datum/sprite_accessory/tails/human/instance = GLOB.tails_list_human[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_tails_list[S.name] = path
var/new_tail
@@ -1663,6 +1688,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_tails_list[S.name] = path
var/new_tail
@@ -1686,6 +1713,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/datum/sprite_accessory/mam_snouts/instance = GLOB.snouts_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_snouts_list[S.name] = path
var/new_snout
@@ -1701,6 +1730,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/datum/sprite_accessory/mam_snouts/instance = GLOB.mam_snouts_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_mam_snouts_list[S.name] = path
var/new_mam_snouts
@@ -1798,6 +1829,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_taur_list[S.name] = path
var/new_taur
@@ -1816,6 +1849,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/datum/sprite_accessory/ears/instance = GLOB.ears_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_ears_list[S.name] = path
var/new_ears
@@ -1829,6 +1864,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_ears_list[S.name] = path
var/new_ears
@@ -1842,6 +1879,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[path]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
+ if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
+ continue
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
snowflake_markings_list[S.name] = path
var/new_mam_body_markings
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index a82054d500..14cd7be547 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -22,7 +22,7 @@
if(!pref_species)
var/rando_race = pick(GLOB.roundstart_races)
pref_species = new rando_race()
- features = random_features()
+ features = random_features(pref_species?.id)
age = rand(AGE_MIN,AGE_MAX)
/datum/preferences/proc/update_preview_icon(equip_job = TRUE)
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
index 92bc8e407b..abe51bf486 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
@@ -71,6 +71,9 @@
//for snowflake/donor specific sprites
var/list/ckeys_allowed
+
+ //For soft-restricting markings to species IDs
+ var/list/recommended_species
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm b/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm
index a5437aaf39..8f043125b2 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm
@@ -38,6 +38,7 @@
color_src = MATRIXED
gender_specific = 0
icon = 'modular_citadel/icons/mob/mam_markings.dmi'
+ recommended_species = list("mammal", "xeno", "slimeperson", "podweak")
/datum/sprite_accessory/mam_body_markings/none
name = "None"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
index 6d2ab1a39b..d47607f6fd 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ipc_synths.dm
@@ -132,10 +132,12 @@
/datum/sprite_accessory/antenna
icon = 'modular_citadel/icons/mob/ipc_antennas.dmi'
color_src = MUTCOLORS2
+ recommended_species = list("ipc")
/datum/sprite_accessory/antenna/none
name = "None"
icon_state = "None"
+ recommended_species = null
/datum/sprite_accessory/antenna/antennae
name = "Angled Antennae"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
index 55bdc31aef..c016e9b119 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
@@ -151,11 +151,12 @@
/datum/sprite_accessory/mam_snouts
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_snouts.dmi'
+ recommended_species = list("mammal", "slimeperson", "insect", "podweak")
/datum/sprite_accessory/mam_snouts/none
name = "None"
icon_state = "none"
-
+ recommended_species = null
/datum/sprite_accessory/mam_snouts/bird
name = "Beak"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
index 21ba17cf40..4dbf9ea0b1 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
@@ -1,5 +1,6 @@
//Synth snouts (This is the most important part)
-/datum/sprite_accessory/mam_snouts/synthliz/synthliz_basic
+/datum/sprite_accessory/mam_snouts/synthliz
+ recommended_species = list("synthliz")
icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
color_src = MUTCOLORS
name = "Synthetic Lizard - Snout"
@@ -24,7 +25,8 @@
icon_state = "synthliz_tertunder"
//Synth body markings
-/datum/sprite_accessory/mam_body_markings/synthliz/synthliz_scutes
+/datum/sprite_accessory/mam_body_markings/synthliz
+ recommended_species = list("synthliz")
icon = 'modular_citadel/icons/mob/synthliz_body_markings.dmi'
name = "Synthetic Lizard - Plates"
icon_state = "synthlizscutes"
@@ -40,26 +42,23 @@
icon_state = "synthlizpecslight"
//Synth tails
-/datum/sprite_accessory/mam_tails/synthliz/synthliz_tail
+/datum/sprite_accessory/mam_tails/synthliz
+ recommended_species = list("synthliz")
icon = 'modular_citadel/icons/mob/synthliz_tails.dmi'
color_src = MUTCOLORS
name = "Synthetic Lizard"
icon_state = "synthliz"
-/datum/sprite_accessory/mam_tails_animated/synthliz/synthliz_tail
+/datum/sprite_accessory/mam_tails_animated/synthliz
+ recommended_species = list("synthliz")
icon = 'modular_citadel/icons/mob/synthliz_tails.dmi'
color_src = MUTCOLORS
name = "Synthetic Lizard"
icon_state = "synthliz"
//Synth Antennae
-/datum/sprite_accessory/antenna/synthliz/synthliz_none
- icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
- color_src = MUTCOLORS
- name = "None"
- icon_state = "None"
-
-/datum/sprite_accessory/antenna/synthliz/synthliz_antennae
+/datum/sprite_accessory/antenna/synthliz
+ recommended_species = list("synthliz")
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
color_src = MUTCOLORS
name = "Synthetic Lizard - Antennae"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
index 5ae3c9a8b3..90980743e1 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
@@ -501,10 +501,12 @@
/datum/sprite_accessory/mam_tails
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
+ recommended_species = list("mammal", "slimeperson", "podweak", "felinid", "insect")
/datum/sprite_accessory/mam_tails/none
name = "None"
icon_state = "none"
+ recommended_species = null
/datum/sprite_accessory/mam_tails_animated
color_src = MATRIXED