diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index dc67de3150..c1686560d6 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -58,8 +58,10 @@
#define BODYPART_DISABLED_DAMAGE 1
#define BODYPART_DISABLED_PARALYSIS 2
+#define DEFAULT_BODYPART_ICON 'icons/mob/human_parts.dmi'
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
+#define DEFAULT_BODYPART_ICON_CITADEL 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
#define MONKEY_BODYPART "monkey"
#define ALIEN_BODYPART "alien"
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 2da96c7f8b..7852ab9d06 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/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm
index 28afea817b..f77cf3adfb 100644
--- a/code/game/machinery/limbgrower.dm
+++ b/code/game/machinery/limbgrower.dm
@@ -138,7 +138,8 @@
limb = new buildpath(loc)
if(selected_category=="human" || selected_category=="lizard") //Species with greyscale parts should be included here
limb.icon = 'icons/mob/human_parts_greyscale.dmi'
- limb.should_draw_greyscale = TRUE
+ limb.base_bp_icon = DEFAULT_BODYPART_ICON_ORGANIC
+ limb.color_src = MUTCOLORS
else
limb.icon = 'icons/mob/human_parts.dmi'
// Set this limb up using the specias name and body zone
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 d5f2ae35ed..a9cf45744e 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/legs_and_taurs.dm b/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm
index b31a41bcc7..fe154ffeec 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm
@@ -30,12 +30,14 @@
var/taur_mode = NONE //Must be a single specific tauric suit variation bitflag. Don't do FLAG_1|FLAG_2
var/alt_taur_mode = NONE //Same as above.
color_src = MATRIXED
+ recommended_species = list("human", "lizard", "insect", "mammal", "xeno", "jelly", "slimeperson", "podweak")
/datum/sprite_accessory/taur/none
dimension_x = 32
center = FALSE
name = "None"
icon_state = "None"
+ recommended_species = null
/datum/sprite_accessory/taur/cow
name = "Cow"
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
new file mode 100644
index 0000000000..a2884ab944
--- /dev/null
+++ b/code/modules/mob/dead/new_player/sprite_accessories/synthliz.dm
@@ -0,0 +1,150 @@
+//Synth snouts (This is the most important part)
+/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"
+ icon_state = "synthliz_basic"
+
+/datum/sprite_accessory/mam_snouts/synthliz/synthliz_under
+ icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
+ color_src = MATRIXED
+ name = "Synthetic Lizard - Snout Under"
+ icon_state = "synthliz_under"
+
+/datum/sprite_accessory/mam_snouts/synthliz/synthliz_tert
+ icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
+ color_src = MATRIXED
+ name = "Synthetic Lizard - Snout Tertiary"
+ icon_state = "synthliz_tert"
+
+/datum/sprite_accessory/mam_snouts/synthliz/synthliz_tertunder
+ icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
+ color_src = MATRIXED
+ name = "Synthetic Lizard - Snout Tertiary Under"
+ icon_state = "synthliz_tertunder"
+
+//Synth body markings
+/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"
+
+/datum/sprite_accessory/mam_body_markings/synthliz/synthliz_pecs
+ icon = 'modular_citadel/icons/mob/synthliz_body_markings.dmi'
+ name = "Synthetic Lizard - Pecs"
+ icon_state = "synthlizpecs"
+
+/datum/sprite_accessory/mam_body_markings/synthliz/synthliz_pecslight
+ icon = 'modular_citadel/icons/mob/synthliz_body_markings.dmi'
+ name = "Synthetic Lizard - Pecs Light"
+ icon_state = "synthlizpecslight"
+
+//Synth tails
+/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
+ 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
+ recommended_species = list("synthliz")
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MUTCOLORS
+ name = "Synthetic Lizard - Antennae"
+ icon_state = "synth_antennae"
+
+/datum/sprite_accessory/antenna/synthliz/synthliz_curled
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MUTCOLORS
+ name = "Synthetic Lizard - Curled"
+ icon_state = "synth_curled"
+
+/datum/sprite_accessory/antenna/synthliz/synthliz_thick
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MUTCOLORS
+ name = "Synthetic Lizard - Thick"
+ icon_state = "synth_thick"
+
+/datum/sprite_accessory/antenna/synthliz/synth_thicklight
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MATRIXED
+ name = "Synthetic Lizard - Thick Light"
+ icon_state = "synth_thicklight"
+
+/datum/sprite_accessory/antenna/synthliz/synth_short
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MUTCOLORS
+ name = "Synthetic Lizard - Short"
+ icon_state = "synth_short"
+
+/datum/sprite_accessory/antenna/synthliz/synth_sharp
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MUTCOLORS
+ name = "Synthetic Lizard - Sharp"
+ icon_state = "synth_sharp"
+
+/datum/sprite_accessory/antenna/synthliz/synth_sharplight
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MATRIXED
+ name = "Synthetic Lizard - Sharp Light"
+ icon_state = "synth_sharplight"
+
+/datum/sprite_accessory/antenna/synthliz/synth_horns
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MUTCOLORS
+ name = "Synthetic Lizard - Horns"
+ icon_state = "synth_horns"
+
+/datum/sprite_accessory/antenna/synthliz/synth_hornslight
+ icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
+ color_src = MATRIXED
+ name = "Synthetic Lizard - Horns Light"
+ icon_state = "synth_hornslight"
+
+//Synth Taurs (Ported from Virgo)
+/datum/sprite_accessory/taur/synthliz
+ name = "Virgo - Synthetic Lizard"
+ icon_state = "synthlizard"
+ taur_mode = STYLE_PAW_TAURIC
+ recommended_species = list("synthliz")
+
+/datum/sprite_accessory/taur/synthliz/inv
+ name = "Virgo - Synthetic Lizard (Inverted)"
+ icon_state = "synthlizardinv"
+
+/datum/sprite_accessory/taur/synthliz/feline
+ name = "Virgo - Synthetic Feline"
+ icon_state = "synthfeline"
+
+/datum/sprite_accessory/taur/synthliz/feline/inv
+ name = "Virgo - Synthetic Feline (Inverted)"
+ icon_state = "synthfelineinv"
+
+/datum/sprite_accessory/taur/synthliz/horse
+ name = "Virgo - Synthetic Horse"
+ icon_state = "synthhorse"
+ taur_mode = STYLE_HOOF_TAURIC
+ alt_taur_mode = STYLE_PAW_TAURIC
+
+/datum/sprite_accessory/taur/synthliz/horse/inv
+ name = "Virgo - Synthetic Horse (Inverted)"
+ icon_state = "synthhorseinv"
+
+/datum/sprite_accessory/taur/synthliz/wolf
+ name = "Virgo - Synthetic Wolf"
+ icon_state = "synthwolf"
+
+/datum/sprite_accessory/taur/synthliz/wolf/inv
+ name = "Virgo - Synthetic Wolf (Inverted)"
+ icon_state = "synthwolfinv"
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
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 92a19b9bd7..85a7a09d5c 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -105,7 +105,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/fixed_mut_color3 = ""
var/whitelisted = 0 //Is this species restricted to certain players?
var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both.
- var/should_draw_citadel = FALSE
+ var/icon_limbs //Overrides the icon used for the limbs of this species. Mainly for downstream, and also because hardcoded icons disgust me. Implemented and maintained as a favor in return for a downstream's implementation of synths.
///////////
// PROCS //
diff --git a/code/modules/mob/living/carbon/human/species_types/bugmen.dm b/code/modules/mob/living/carbon/human/species_types/bugmen.dm
index e2e41330fb..6bd8a44e0a 100644
--- a/code/modules/mob/living/carbon/human/species_types/bugmen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/bugmen.dm
@@ -13,7 +13,7 @@
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/insect
liked_food = MEAT | FRUIT
disliked_food = TOXIC
- should_draw_citadel = TRUE
+ icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
/datum/species/insect/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
index ab86b2cc5d..608d71e2c5 100644
--- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
@@ -2,7 +2,7 @@
name = "Anthromorph"
id = "mammal"
default_color = "4B4B4B"
- should_draw_citadel = TRUE
+ icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BEAST
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "deco_wings", "taur", "horns", "legs")
@@ -55,7 +55,7 @@
id = "xeno"
say_mod = "hisses"
default_color = "00FF00"
- should_draw_citadel = TRUE
+ icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
species_traits = list(MUTCOLORS,EYECOLOR,LIPS)
mutant_bodyparts = list("xenotail", "xenohead", "xenodorsal", "mam_body_markings", "taur", "legs")
default_features = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = "Xeno","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade")
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 add0e17c43..b7305a9228 100644
--- a/code/modules/mob/living/carbon/human/species_types/ipc.dm
+++ b/code/modules/mob/living/carbon/human/species_types/ipc.dm
@@ -3,7 +3,7 @@
id = "ipc"
say_mod = "beeps"
default_color = "00FF00"
- should_draw_citadel = TRUE
+ icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
blacklisted = 0
sexes = 0
species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING)
diff --git a/code/modules/mob/living/carbon/human/species_types/synthliz.dm b/code/modules/mob/living/carbon/human/species_types/synthliz.dm
new file mode 100644
index 0000000000..40441c45fd
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/species_types/synthliz.dm
@@ -0,0 +1,53 @@
+/datum/species/synthliz
+ name = "Synthetic Lizardperson"
+ id = "synthliz"
+ icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
+ say_mod = "beeps"
+ default_color = "00FF00"
+ species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR)
+ inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
+ mutant_bodyparts = list("ipc_antenna","mam_tail", "mam_snouts","legs", "mam_body_markings", "taur")
+ default_features = list("ipc_antenna" = "Synthetic Lizard - Antennae","mam_tail" = "Synthetic Lizard", "mam_snouts" = "Synthetic Lizard - Snout", "legs" = "Digitigrade", "mam_body_markings" = "Synthetic Lizard - Plates", "taur" = "None")
+ meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
+ gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
+ mutanttongue = /obj/item/organ/tongue/robot/ipc
+ //Just robo looking parts.
+ mutant_heart = /obj/item/organ/heart/ipc
+ mutantlungs = /obj/item/organ/lungs/ipc
+ mutantliver = /obj/item/organ/liver/ipc
+ mutantstomach = /obj/item/organ/stomach/ipc
+ mutanteyes = /obj/item/organ/eyes/ipc
+
+ exotic_bloodtype = "S"
+
+
+/datum/species/synthliz/qualifies_for_rank(rank, list/features)
+ return TRUE
+
+//I wag in death
+/datum/species/synthliz/spec_death(gibbed, mob/living/carbon/human/H)
+ if(H)
+ stop_wagging_tail(H)
+
+/datum/species/synthliz/spec_stun(mob/living/carbon/human/H,amount)
+ if(H)
+ stop_wagging_tail(H)
+ . = ..()
+
+/datum/species/synthliz/can_wag_tail(mob/living/carbon/human/H)
+ return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
+
+/datum/species/synthliz/is_wagging_tail(mob/living/carbon/human/H)
+ return ("mam_waggingtail" in mutant_bodyparts)
+
+/datum/species/synthliz/start_wagging_tail(mob/living/carbon/human/H)
+ if("mam_tail" in mutant_bodyparts)
+ mutant_bodyparts -= "mam_tail"
+ mutant_bodyparts |= "mam_waggingtail"
+ H.update_body()
+
+/datum/species/synthliz/stop_wagging_tail(mob/living/carbon/human/H)
+ if("mam_waggingtail" in mutant_bodyparts)
+ mutant_bodyparts -= "mam_waggingtail"
+ mutant_bodyparts |= "mam_tail"
+ H.update_body()
\ No newline at end of file
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index bdea05decd..4b56ab6cb8 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -41,9 +41,9 @@
var/skin_tone = ""
var/body_gender = ""
var/species_id = ""
- var/should_draw_citadel = FALSE
+ var/color_src
+ var/base_bp_icon //Overrides the icon being used for this limb. This is mainly for downstreams, implemented and maintained as a favor in return for implementing synths. And also because should_draw_* for icon overrides was pretty messy. You're welcome.
var/should_draw_gender = FALSE
- var/should_draw_greyscale = FALSE
var/species_color = ""
var/mutation_color = ""
var/no_update = 0
@@ -283,9 +283,9 @@
if(change_icon_to_default)
if(status == BODYPART_ORGANIC)
- icon = DEFAULT_BODYPART_ICON_ORGANIC
+ icon = base_bp_icon || DEFAULT_BODYPART_ICON_ORGANIC
else if(status == BODYPART_ROBOTIC)
- icon = DEFAULT_BODYPART_ICON_ROBOTIC
+ icon = base_bp_icon || DEFAULT_BODYPART_ICON_ROBOTIC
if(owner)
owner.updatehealth()
@@ -313,7 +313,8 @@
species_id = "husk" //overrides species_id
dmg_overlay_type = "" //no damage overlay shown when husked
should_draw_gender = FALSE
- should_draw_greyscale = FALSE
+ color_src = FALSE
+ base_bp_icon = DEFAULT_BODYPART_ICON
no_update = TRUE
body_markings = "husk" // reeee
aux_marking = "husk"
@@ -323,11 +324,11 @@
if(!animal_origin)
var/mob/living/carbon/human/H = C
- should_draw_greyscale = FALSE
+ color_src = FALSE
var/datum/species/S = H.dna.species
+ base_bp_icon = S?.icon_limbs || DEFAULT_BODYPART_ICON
species_id = S.limbs_id
- should_draw_citadel = S.should_draw_citadel // Citadel Addition
species_flags_list = H.dna.species.species_traits
//body marking memes
@@ -342,7 +343,7 @@
if(S.use_skintones)
skin_tone = H.skin_tone
- should_draw_greyscale = TRUE
+ base_bp_icon = (base_bp_icon == DEFAULT_BODYPART_ICON) ? DEFAULT_BODYPART_ICON_ORGANIC : base_bp_icon
else
skin_tone = ""
@@ -354,9 +355,12 @@
species_color = S.fixed_mut_color
else
species_color = H.dna.features["mcolor"]
- should_draw_greyscale = TRUE
+ base_bp_icon = (base_bp_icon == DEFAULT_BODYPART_ICON) ? DEFAULT_BODYPART_ICON_ORGANIC : base_bp_icon
else
species_color = ""
+
+ if(base_bp_icon != DEFAULT_BODYPART_ICON)
+ color_src = MUTCOLORS //TODO - Add color matrix support to base limbs
if("legs" in S.default_features)
if(body_zone == BODY_ZONE_L_LEG || body_zone == BODY_ZONE_R_LEG)
@@ -371,8 +375,8 @@
if(Smark)
body_markings_icon = Smark.icon
if(H.dna.features["mam_body_markings"] != "None")
- body_markings = lowertext(H.dna.features["mam_body_markings"])
- aux_marking = lowertext(H.dna.features["mam_body_markings"])
+ body_markings = Smark?.icon_state || lowertext(H.dna.features["mam_body_markings"])
+ aux_marking = Smark?.icon_state || lowertext(H.dna.features["mam_body_markings"])
else
body_markings = "plain"
aux_marking = "plain"
@@ -462,32 +466,16 @@
should_draw_gender = FALSE
if(is_organic_limb())
- if(should_draw_greyscale)
- limb.icon = 'icons/mob/human_parts_greyscale.dmi'
- if(should_draw_gender)
- limb.icon_state = "[species_id]_[body_zone]_[icon_gender]"
- else if(use_digitigrade)
+ limb.icon = base_bp_icon || 'icons/mob/human_parts.dmi'
+ if(should_draw_gender)
+ limb.icon_state = "[species_id]_[body_zone]_[icon_gender]"
+ else if (use_digitigrade)
+ if(base_bp_icon == DEFAULT_BODYPART_ICON_ORGANIC) //Compatibility hack for the current iconset.
limb.icon_state = "[digitigrade_type]_[use_digitigrade]_[body_zone]"
else
- limb.icon_state = "[species_id]_[body_zone]"
+ limb.icon_state = "[species_id]_[digitigrade_type]_[use_digitigrade]_[body_zone]"
else
- limb.icon = 'icons/mob/human_parts.dmi'
- if(should_draw_gender)
- limb.icon_state = "[species_id]_[body_zone]_[icon_gender]"
- else if(use_digitigrade)
- limb.icon_state = "[species_id]_[digitigrade_type]_[use_digitigrade]_[body_zone]"
- else
- limb.icon_state = "[species_id]_[body_zone]"
-
- // Citadel Start
- if(should_draw_citadel)
- limb.icon = 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
- if(should_draw_gender)
- limb.icon_state = "[species_id]_[body_zone]_[icon_gender]"
- else if(use_digitigrade)
- limb.icon_state = "[species_id]_[digitigrade_type]_[use_digitigrade]_[body_zone]"
- else
- limb.icon_state = "[species_id]_[body_zone]"
+ limb.icon_state = "[species_id]_[body_zone]"
// Body markings
if(!isnull(body_markings))
@@ -555,7 +543,7 @@
. += marking
return
- if(should_draw_greyscale)
+ if(color_src) //TODO - add color matrix support for base species limbs
var/draw_color = mutation_color || species_color || (skin_tone && skintone2hex(skin_tone))
if(draw_color)
limb.color = "#[draw_color]"
diff --git a/config/game_options.txt b/config/game_options.txt
index 5be76ae60d..4113a90e6d 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -421,6 +421,7 @@ ROUNDSTART_RACES human
## Races that are strictly worse than humans that could probably be turned on without balance concerns
ROUNDSTART_RACES lizard
+ROUNDSTART_RACES synthliz
#ROUNDSTART_RACES fly
#ROUNDSTART_RACES insect
ROUNDSTART_RACES plasmaman
diff --git a/modular_citadel/icons/mob/mam_taur.dmi b/modular_citadel/icons/mob/mam_taur.dmi
index 84367ebf0a..db1f001fae 100644
Binary files a/modular_citadel/icons/mob/mam_taur.dmi and b/modular_citadel/icons/mob/mam_taur.dmi differ
diff --git a/modular_citadel/icons/mob/mutant_bodyparts.dmi b/modular_citadel/icons/mob/mutant_bodyparts.dmi
index 8ff4a3ddb5..95b121b453 100644
Binary files a/modular_citadel/icons/mob/mutant_bodyparts.dmi and b/modular_citadel/icons/mob/mutant_bodyparts.dmi differ
diff --git a/modular_citadel/icons/mob/synthliz_antennas.dmi b/modular_citadel/icons/mob/synthliz_antennas.dmi
new file mode 100644
index 0000000000..0c75578ee9
Binary files /dev/null and b/modular_citadel/icons/mob/synthliz_antennas.dmi differ
diff --git a/modular_citadel/icons/mob/synthliz_body_markings.dmi b/modular_citadel/icons/mob/synthliz_body_markings.dmi
new file mode 100644
index 0000000000..52f9027f03
Binary files /dev/null and b/modular_citadel/icons/mob/synthliz_body_markings.dmi differ
diff --git a/modular_citadel/icons/mob/synthliz_snouts.dmi b/modular_citadel/icons/mob/synthliz_snouts.dmi
new file mode 100644
index 0000000000..908ac583d0
Binary files /dev/null and b/modular_citadel/icons/mob/synthliz_snouts.dmi differ
diff --git a/modular_citadel/icons/mob/synthliz_tails.dmi b/modular_citadel/icons/mob/synthliz_tails.dmi
new file mode 100644
index 0000000000..6aaf4ad391
Binary files /dev/null and b/modular_citadel/icons/mob/synthliz_tails.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 50ff19916f..1fe4fe9ce1 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2139,6 +2139,7 @@
#include "code\modules\mob\dead\new_player\sprite_accessories\pines.dm"
#include "code\modules\mob\dead\new_player\sprite_accessories\snouts.dm"
#include "code\modules\mob\dead\new_player\sprite_accessories\socks.dm"
+#include "code\modules\mob\dead\new_player\sprite_accessories\synthliz.dm"
#include "code\modules\mob\dead\new_player\sprite_accessories\tails.dm"
#include "code\modules\mob\dead\new_player\sprite_accessories\undershirt.dm"
#include "code\modules\mob\dead\new_player\sprite_accessories\underwear.dm"
@@ -2261,6 +2262,7 @@
#include "code\modules\mob\living\carbon\human\species_types\podpeople.dm"
#include "code\modules\mob\living\carbon\human\species_types\shadowpeople.dm"
#include "code\modules\mob\living\carbon\human\species_types\skeletons.dm"
+#include "code\modules\mob\living\carbon\human\species_types\synthliz.dm"
#include "code\modules\mob\living\carbon\human\species_types\synths.dm"
#include "code\modules\mob\living\carbon\human\species_types\vampire.dm"
#include "code\modules\mob\living\carbon\human\species_types\zombies.dm"