diff --git a/code/__DEFINES/~skyrat_defines/jobs.dm b/code/__DEFINES/~skyrat_defines/jobs.dm
index c62efae5e83..775e4ffed2f 100644
--- a/code/__DEFINES/~skyrat_defines/jobs.dm
+++ b/code/__DEFINES/~skyrat_defines/jobs.dm
@@ -1,4 +1,5 @@
#define JOB_UNAVAILABLE_QUIRK 6
+#define JOB_UNAVAILABLE_SPECIES 7
#define SEC_RESTRICTED_QUIRKS "Blind" = TRUE, "Blood Deficiency" = TRUE, "Brain Tumor" = TRUE, "Deaf" = TRUE, "Paraplegic" = TRUE, "Mute" = TRUE, "Foreigner" = TRUE, "Pacifist" = TRUE
#define HEAD_RESTRICTED_QUIRKS "Blind" = TRUE, "Deaf" = TRUE, "Mute" = TRUE, "Foreigner" = TRUE
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 7d2d390beff..da7400e9858 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -88,6 +88,8 @@ SUBSYSTEM_DEF(job)
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
if(job.has_banned_quirk(player.client.prefs))
return FALSE
+ if(job.has_banned_species(player.client.prefs))
+ return FALSE
//SKYRAT EDIT END
if(job.required_playtime_remaining(player.client))
return FALSE
@@ -117,6 +119,9 @@ SUBSYSTEM_DEF(job)
if(job.has_banned_quirk(player.client.prefs))
JobDebug("FOC job not compatible with quirks, Player: [player]")
continue
+ if(job.has_banned_species(player.client.prefs))
+ JobDebug("FOC job not compatible with species, Player: [player]")
+ continue
//SKYRAT EDIT END
if(job.required_playtime_remaining(player.client))
JobDebug("FOC player not enough xp, Player: [player]")
@@ -160,6 +165,9 @@ SUBSYSTEM_DEF(job)
if(job.has_banned_quirk(player.client.prefs))
JobDebug("GRJ player has incompatible quirk, Player: [player]")
continue
+ if(job.has_banned_species(player.client.prefs))
+ JobDebug("GRJ player has incompatible species, Player: [player]")
+ continue
//SKYRAT EDIT END
if(job.required_playtime_remaining(player.client))
@@ -346,6 +354,9 @@ SUBSYSTEM_DEF(job)
if(job.has_banned_quirk(player.client.prefs))
JobDebug("DO player has incompatible quirk, Player: [player], Job:[job.title]")
continue
+ if(job.has_banned_species(player.client.prefs))
+ JobDebug("DO player has incompatible species, Player: [player], Job:[job.title]")
+ continue
//SKYRAT EDIT END
if(job.required_playtime_remaining(player.client))
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index ddaa82c70af..4a859de9351 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -19,9 +19,17 @@
assignedrole = "Lifebringer"
/obj/effect/mob_spawn/human/seed_vault/special(mob/living/new_spawn)
+ //SKYRAT EDIT CHANGE BEGIN
+ /*
var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
"Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
new_spawn.fully_replace_character_name(null,plant_name)
+ */
+ if(!is_pref_char)
+ var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
+ "Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
+ new_spawn.fully_replace_character_name(null,plant_name)
+ //SKYRAT EDIT CHANGE END
if(ishuman(new_spawn))
var/mob/living/carbon/human/H = new_spawn
H.underwear = "Nude" //You're a plant, partner
@@ -99,7 +107,11 @@
return FALSE
/obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn)
- new_spawn.fully_replace_character_name(null,random_unique_lizard_name(gender))
+ //SKYRAT EDIT CHANGE BEGIN
+ //new_spawn.fully_replace_character_name(null,random_unique_lizard_name(gender)) //ORIGINAL
+ if(!is_pref_char)
+ new_spawn.fully_replace_character_name(null,random_unique_lizard_name(gender))
+ //SKYRAT EDIT CHANGE END
to_chat(new_spawn, "Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Invade the strange structure of the outsiders if you must. Do not cause unnecessary destruction, as littering the wastes with ugly wreckage is certain to not gain you favor. Glory to the Necropolis!")
new_spawn.mind.add_antag_datum(/datum/antagonist/ashwalker, team)
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 27ed0499cd4..10c094d8f8d 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -43,6 +43,10 @@
var/ghost_role = alert("Become [mob_name]? (Warning, You can no longer be revived!)",,"Yes","No")
if(ghost_role == "No" || !loc || QDELETED(user))
return
+ //SKYRAT EDIT ADDITION BEGIN
+ if(!extra_prompts(user))
+ return
+ //SKYRAT EDIT ADDITION END
if(!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER) && !(flags_1 & ADMIN_SPAWNED_1))
to_chat(user, "An admin has temporarily disabled non-admin ghost roles!")
return
@@ -57,7 +61,8 @@
if(QDELETED(src) || QDELETED(user))
return
log_game("[key_name(user)] became [mob_name]")
- create(ckey = user.ckey)
+ //create(ckey = user.ckey) //ORIGINAL
+ create(user.ckey, null, user) //SKYRAT EDIT CHANGE
/obj/effect/mob_spawn/Initialize(mapload)
. = ..()
@@ -74,16 +79,11 @@
GLOB.mob_spawners -= name
return ..()
-/obj/effect/mob_spawn/proc/allow_spawn(mob/user) //Override this to add spawn limits to a ghost role
+//SKYRAT EDIT ADDITION BEGIN
+/obj/effect/mob_spawn/proc/extra_prompts(mob/user)
return TRUE
-/obj/effect/mob_spawn/proc/special(mob/M)
- return
-
-/obj/effect/mob_spawn/proc/equip(mob/M)
- return
-
-/obj/effect/mob_spawn/proc/create(ckey, newname)
+/obj/effect/mob_spawn/proc/create_mob(mob/user, newname)
var/mob/living/M = new mob_type(get_turf(src)) //living mobs only
if(!random || newname)
if(newname)
@@ -93,6 +93,34 @@
if(!mob_gender)
mob_gender = pick(MALE, FEMALE)
M.gender = mob_gender
+ return M
+//SKYRAT EDIT ADDITION END
+
+/obj/effect/mob_spawn/proc/allow_spawn(mob/user) //Override this to add spawn limits to a ghost role
+ return TRUE
+
+/obj/effect/mob_spawn/proc/special(mob/M)
+ return
+
+/obj/effect/mob_spawn/proc/equip(mob/M)
+ return
+
+///obj/effect/mob_spawn/proc/create(ckey, newname) //ORIGINAL
+/obj/effect/mob_spawn/proc/create(ckey, newname, mob/user) //SKYRAT EDIT CHANGE
+ //SKYRAT EDIT CHANGE BEGIN
+ //var/mob/living/M = new mob_type(get_turf(src)) //ORIGINAL
+ var/mob/living/M = create_mob(user, newname)
+ /*
+ if(!random || newname)
+ if(newname)
+ M.real_name = newname
+ else
+ M.real_name = mob_name ? mob_name : M.name
+ if(!mob_gender)
+ mob_gender = pick(MALE, FEMALE)
+ M.gender = mob_gender
+ */
+ //SKYRAT EDIT CHANGE END
if(faction)
M.faction = list(faction)
if(disease)
@@ -140,7 +168,8 @@
/obj/effect/mob_spawn/human
mob_type = /mob/living/carbon/human
//Human specific stuff.
- var/mob_species = null //Set to make them a mutant race such as lizard or skeleton. Uses the datum typepath instead of the ID.
+ //var/mob_species = null //Set to make them a mutant race such as lizard or skeleton. Uses the datum typepath instead of the ID. //ORIGINAL
+ var/mob_species = /datum/species/human //SKYRAT EDIT CHANGE
var/datum/outfit/outfit = /datum/outfit //If this is a path, it will be instanced in Initialize()
var/disable_pda = TRUE
var/disable_sensors = TRUE
@@ -175,6 +204,93 @@
var/hairstyle
var/facial_hairstyle
var/skin_tone
+ //SKYRAT EDIT ADDITION BEGIN
+ var/can_use_pref_char = TRUE
+ var/can_use_alias = FALSE
+ var/any_station_species = FALSE
+ var/chosen_alias
+ var/is_pref_char
+ var/last_ckey //For validation of the user
+ //SKYRAT EDIT ADDITION END
+
+//SKYRAT EDIT ADDITION BEGIN
+/obj/effect/mob_spawn/human/extra_prompts(mob/user)
+ last_ckey = user.ckey
+ chosen_alias = null
+ is_pref_char = null
+ if(can_use_pref_char)
+ var/initial_string = "Would you like to spawn as a randomly created character, or use the one currently selected in your preferences?"
+ var/action = alert(user, initial_string, "", "Use Random Character", "Use Character From Preferences")
+ if(action && action == "Use Character From Preferences")
+ var/warning_string = "WARNING: This spawner will use your currently selected character in prefs ([user.client.prefs.real_name])\nMake sure that the character is not used as a station crew, or would have a good reason to be this role.(ie. intern in Space Hotel)\nUSING STATION CHARACTERS FOR SYNDICATE OR HOSTILE ROLES IS PROHIBITED WILL GET YOU BANNED!\nConsider making a character dedicated to the role.\nDo you wanna proceed?"
+ var/action2 = alert(user, warning_string, "", "Yes", "No")
+ if(action2 && action2 == "Yes")
+ is_pref_char = TRUE
+ else
+ return FALSE
+
+ if(can_use_alias)
+ var/action = alert(user, "Would you like to use an alias?\nIf you do, your name will be changed to that", "", "Dont Use Alias", "Use Alias")
+ if(action && action == "Use Alias")
+ var/msg = reject_bad_name(input(user, "Set your character's alias for this role", "Alias") as text|null)
+ if(!msg)
+ return FALSE
+ chosen_alias = msg
+
+ if(is_pref_char)
+ if(!any_station_species && user.client.prefs.pref_species.type != mob_species)
+ alert(user, "Sorry, This spawner is limited to those species: [mob_species]. Please switch your character.", "", "Ok")
+ return FALSE
+
+ if(QDELETED(src) || QDELETED(user))
+ return FALSE
+ //What's happening here?
+ //This function is fairly asynchronous and doesnt keep variables in context, so this check is for validation that we are using the correct user
+ if(last_ckey != user.ckey)
+ return FALSE
+ return TRUE
+
+/obj/effect/mob_spawn/human/create_mob(mob/user, newname)
+ var/mob/living/carbon/human/H = new mob_type(get_turf(src))
+ if(is_pref_char && user?.client)
+ user.client.prefs.copy_to(H)
+ H.dna.update_dna_identity()
+ if(chosen_alias)
+ H.name = chosen_alias
+ H.real_name = chosen_alias
+ //Pre-job equips so Voxes dont die
+ H.dna.species.before_equip_job(null, H)
+ H.regenerate_icons()
+ else
+ if(!random || newname)
+ if(newname)
+ H.real_name = newname
+ else
+ H.real_name = mob_name ? mob_name : H.name
+ if(!mob_gender)
+ mob_gender = pick(MALE, FEMALE)
+ H.gender = mob_gender
+ if(mob_species)
+ H.set_species(mob_species)
+ H.underwear = "Nude"
+ H.undershirt = "Nude"
+ H.socks = "Nude"
+ if(hairstyle)
+ H.hairstyle = hairstyle
+ else
+ H.hairstyle = random_hairstyle(H.gender)
+ if(facial_hairstyle)
+ H.facial_hairstyle = facial_hairstyle
+ else
+ H.facial_hairstyle = random_facial_hairstyle(H.gender)
+ if(skin_tone)
+ H.skin_tone = skin_tone
+ else
+ H.skin_tone = random_skin_tone()
+ H.update_hair()
+ H.update_body()
+ return H
+//SKYRAT EDIT ADDITION END
/obj/effect/mob_spawn/human/Initialize()
if(ispath(outfit))
@@ -184,12 +300,18 @@
return ..()
/obj/effect/mob_spawn/human/equip(mob/living/carbon/human/H)
+ //SKYRAT EDIT REMOVAL BEGIN - MOVED
+ /*
if(mob_species)
H.set_species(mob_species)
+ */
+ //SKYRAT EDIT REMOVAL END
if(husk)
H.Drain()
else //Because for some reason I can't track down, things are getting turned into husks even if husk = false. It's in some damage proc somewhere.
H.cure_husk()
+ //SKYRAT EDIT REMOVAL BEGIN - MOVED
+ /*
H.underwear = "Nude"
H.undershirt = "Nude"
H.socks = "Nude"
@@ -207,6 +329,8 @@
H.skin_tone = random_skin_tone()
H.update_hair()
H.update_body()
+ */
+ //SKYRAT EDIT REMOVAL END
if(outfit)
var/static/list/slots = list("uniform", "r_hand", "l_hand", "suit", "shoes", "gloves", "ears", "glasses", "mask", "head", "belt", "r_pocket", "l_pocket", "back", "id", "neck", "backpack_contents", "suit_store")
for(var/slot in slots)
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 36d36d263c0..da456082488 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -265,6 +265,8 @@
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
if(JOB_UNAVAILABLE_QUIRK)
return "[jobtitle] is restricted from your quirks."
+ if(JOB_UNAVAILABLE_SPECIES)
+ return "[jobtitle] is restricted from your species."
//SKYRAT EDIT END
return "Error: Unknown job availability."
@@ -292,6 +294,8 @@
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
if(job.has_banned_quirk(client.prefs))
return JOB_UNAVAILABLE_QUIRK
+ if(job.has_banned_species(client.prefs))
+ return JOB_UNAVAILABLE_SPECIES
//SKYRAT EDIT END
if(latejoin && !job.special_check_latejoin(client))
return JOB_UNAVAILABLE_GENERIC
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 1c1baa5fd75..e921f6a2929 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -208,6 +208,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
* This proc generates which species are available to pick from in character setup.
* If there are no available roundstart species, defaults to human.
*/
+//SKYRAT EDIT REMOVAL BEGIN - MOVED - CUSTOMIZATION
+/*
/proc/generate_selectable_species()
for(var/I in subtypesof(/datum/species))
var/datum/species/S = new I
@@ -216,6 +218,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
qdel(S)
if(!GLOB.roundstart_races.len)
GLOB.roundstart_races += "human"
+*/
+//SKYRAT EDIT REMOVAL END
/**
* Checks if a species is eligible to be picked at roundstart.
diff --git a/modular_skyrat/master_files/code/game/objects/ghost_role_spawners.dm b/modular_skyrat/master_files/code/game/objects/ghost_role_spawners.dm
new file mode 100644
index 00000000000..31ac5247d80
--- /dev/null
+++ b/modular_skyrat/master_files/code/game/objects/ghost_role_spawners.dm
@@ -0,0 +1,47 @@
+/obj/effect/mob_spawn/human/syndicatespace
+ can_use_alias = TRUE
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/beach/alive
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/exile
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/hermit
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/prisoner_transport
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/hotel_staff
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/syndicate
+ can_use_alias = TRUE
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/alive/space_bar_patron
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/nanotrasensoldier/alive
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/commander/alive
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/doctor/alive
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/lavaland_syndicate
+ can_use_alias = TRUE
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/oldsec
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/oldeng
+ any_station_species = TRUE
+
+/obj/effect/mob_spawn/human/oldsci
+ any_station_species = TRUE
diff --git a/modular_skyrat/master_files/code/modules/clothing/non_anthro_clothes.dm b/modular_skyrat/master_files/code/modules/clothing/non_anthro_clothes.dm
index 1a0d38e969a..6bcaf15d6ef 100644
--- a/modular_skyrat/master_files/code/modules/clothing/non_anthro_clothes.dm
+++ b/modular_skyrat/master_files/code/modules/clothing/non_anthro_clothes.dm
@@ -2,6 +2,12 @@
//Please make sure you double check a sprite before adding an entry into this as some clothing items do require alternate sprites.area
//HEAD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+/obj/item/clothing/head/festive
+ mutant_variants = NONE
+
+/obj/item/clothing/head/helmet/gladiator
+ mutant_variants = NONE
+
/obj/item/clothing/head/chefhat
mutant_variants = NONE
@@ -158,6 +164,9 @@
//UNDER>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+/obj/item/clothing/under/costume/gladiator/ash_walker
+ mutant_variants = NONE
+
/obj/item/clothing/under/misc/gear_harness
mutant_variants = NONE
diff --git a/modular_skyrat/modules/customization/modules/client/preferences.dm b/modular_skyrat/modules/customization/modules/client/preferences.dm
index 0d2e371e88f..6ebb5f85687 100644
--- a/modular_skyrat/modules/customization/modules/client/preferences.dm
+++ b/modular_skyrat/modules/customization/modules/client/preferences.dm
@@ -1265,6 +1265,9 @@ GLOBAL_LIST_INIT(food, list(
if(job.has_banned_quirk(src))
HTML += "[rank]
\[BAD QUIRKS\] | "
continue
+ if(job.has_banned_species(src))
+ HTML += "[rank] \[BAD SPECIES\] | "
+ continue
if((job_preferences[SSjob.overflow_role] == JP_LOW) && (rank != SSjob.overflow_role) && !is_banned_from(user.ckey, SSjob.overflow_role))
HTML += "[rank] | "
continue
@@ -1896,6 +1899,17 @@ GLOBAL_LIST_INIT(food, list(
switch(href_list["preference"])
+ if("set_species")
+ needs_update = TRUE
+ var/species = href_list["selected_species"]
+ var/newtype = GLOB.species_list[species]
+ if(newtype)
+ set_new_species(newtype)
+ user << browse(null, "window=species_menu")
+
+ if("close_species")
+ user << browse(null, "window=species_menu")
+
if("ghostform")
if(unlock_content)
var/new_form = input(user, "Thanks for supporting BYOND - Choose your ghostly form:","Thanks for supporting BYOND",null) as null|anything in GLOB.ghost_forms
@@ -2168,18 +2182,8 @@ GLOBAL_LIST_INIT(food, list(
features["custom_species"] = null
if("species")
- needs_update = TRUE
- var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_races
-
- if(result)
- var/newtype = GLOB.species_list[result]
- set_new_species(newtype)
- /*//Now that we changed our species, we must verify that the mutant colour is still allowed.
- var/temp_hsv = RGBtoHSV(features["mcolor"])
- if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#7F7F7F")[3]))
- features["mcolor"] = pref_species.default_color*/
- if(randomise[RANDOM_NAME])
- real_name = pref_species.random_name(gender)
+ ShowSpeciesMenu(user)
+ return TRUE
if("mutant_color")
needs_update = TRUE
@@ -2790,7 +2794,7 @@ GLOBAL_LIST_INIT(food, list(
var/datum/species/chosen_species
chosen_species = pref_species.type
- if(roundstart_checks && !(pref_species.id in GLOB.roundstart_races) && !(pref_species.id in (CONFIG_GET(keyed_list/roundstart_no_hard_check))))
+ if(roundstart_checks && !(pref_species.id in GLOB.customizable_races))
chosen_species = /datum/species/human
set_new_species(/datum/species/human)
save_character()
@@ -2910,6 +2914,59 @@ GLOBAL_LIST_INIT(food, list(
else
return FALSE
+/datum/preferences/proc/ShowSpeciesMenu(mob/user)
+ var/list/dat = list()
+ dat += "Choose your character's species:"
+ dat += "Back"
+ dat += "
"
+ var/list/playables = list()
+ var/list/unplayables = list()
+ for(var/id in GLOB.customizable_races)
+ if(GLOB.roundstart_races[id])
+ playables += id
+ else
+ unplayables += id
+ var/even = TRUE
+ var/background_cl
+ dat += ""
+ dat += " | "
+ dat += " | "
+ dat += " | "
+ dat += "
"
+ for(var/id in playables)
+ even = !even
+ var/datum/species/S = GLOB.species_list[id]
+ background_cl = (even ? "#13171C" : "#19232C")
+ dat += ""
+ dat += "| [initial(S.name)] | "
+ dat += "[initial(S.flavor_text)] | "
+ dat += "Choose | "
+ dat += "
"
+ dat += ""
+ dat += "
"
+ dat += "Below you have species which you cannot play on station, however you can customize them and join as an event or ghost role"
+ dat += "
"
+ dat += ""
+ dat += " | "
+ dat += " | "
+ dat += " | "
+ dat += "
"
+ for(var/id in unplayables)
+ even = !even
+ var/datum/species/S = GLOB.species_list[id]
+ background_cl = (even ? "#852119" : "#9c2a21")
+ dat += ""
+ dat += "| [initial(S.name)] | "
+ dat += "[initial(S.flavor_text)] | "
+ dat += "Choose | "
+ dat += "
"
+ dat += ""
+
+ var/datum/browser/popup = new(user, "species_menu", "Species Choice
", 900, 600)
+ popup.set_window_options("can_close=0")
+ popup.set_content(dat.Join())
+ popup.open(FALSE)
+
// old bobcode copypaste, handle with caution
/datum/preferences/proc/SetFood(mob/user)
var/list/dat = list()
diff --git a/modular_skyrat/modules/customization/modules/jobs/_job.dm b/modular_skyrat/modules/customization/modules/jobs/_job.dm
index 1b903afe233..90474fa89f7 100644
--- a/modular_skyrat/modules/customization/modules/jobs/_job.dm
+++ b/modular_skyrat/modules/customization/modules/jobs/_job.dm
@@ -5,6 +5,10 @@
var/loadout = TRUE
//List of banned quirks in their names(dont blame me, that's how they're stored), players can't join as the job if they have the quirk. Associative for the purposes of performance
var/list/banned_quirks
+ //Whitelist of allowed species for this job. If not specified then all roundstart races can be used. Associative with TRUE
+ var/list/species_whitelist
+ //Blacklist of species for this job.
+ var/list/species_blacklist
/datum/job/proc/has_banned_quirk(datum/preferences/pref)
if(!pref) //No preferences? We'll let you pass, this time (just a precautionary check,you dont wanna mess up gamemode setting logic)
@@ -15,6 +19,16 @@
return TRUE
return FALSE
+/datum/job/proc/has_banned_species(datum/preferences/pref)
+ var/my_id = pref.pref_species.id
+ if(species_whitelist && !species_whitelist[my_id])
+ return TRUE
+ else if(!GLOB.roundstart_races[my_id])
+ return TRUE
+ if(species_blacklist && species_blacklist[my_id])
+ return TRUE
+ return FALSE
+
/datum/job/assistant
no_dresscode = TRUE
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
index caa33801ed4..1eb07035f27 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
@@ -1,3 +1,17 @@
+GLOBAL_LIST_EMPTY(customizable_races)
+
+/proc/generate_selectable_species()
+ for(var/I in subtypesof(/datum/species))
+ var/datum/species/S = new I
+ if(S.check_roundstart_eligible())
+ GLOB.roundstart_races[S.id] = TRUE
+ GLOB.customizable_races[S.id] = TRUE
+ else if (S.always_customizable)
+ GLOB.customizable_races[S.id] = TRUE
+ qdel(S)
+ if(!GLOB.roundstart_races.len)
+ GLOB.roundstart_races["human"] = TRUE
+
/datum/species
mutant_bodyparts = list()
///Self explanatory
@@ -12,6 +26,10 @@
var/reagent_flags = PROCESS_ORGANIC
///Whether a species can use augmentations in preferences
var/can_augment = TRUE
+ ///If a species can always be picked in prefs for the purposes of customizing it for ghost roles or events
+ var/always_customizable = FALSE
+ ///Flavor text of the species displayed on character creation screeen
+ var/flavor_text = "No description."
/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
var/list/standing = list()
@@ -276,6 +294,10 @@
can_have_genitals = FALSE
can_augment = FALSE
+/datum/species/pod
+ name = "Primal Podperson"
+ always_customizable = TRUE
+
/datum/species/proc/get_random_features()
var/list/returned = MANDATORY_FEATURE_LIST
returned["mcolor"] = random_short_color()
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm
index 20ea1e4f276..ca69cc34941 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm
@@ -26,3 +26,4 @@
/datum/species/lizard/ashwalker
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE,HAS_FLESH,HAS_BONE,NO_UNDERWEAR)
+ always_customizable = TRUE
diff --git a/modular_skyrat/modules/emotes/code/dna_screams.dm b/modular_skyrat/modules/emotes/code/dna_screams.dm
index e1027e4bc51..67b65bb63f6 100644
--- a/modular_skyrat/modules/emotes/code/dna_screams.dm
+++ b/modular_skyrat/modules/emotes/code/dna_screams.dm
@@ -1,96 +1,72 @@
/datum/species
var/list/screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_m1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_m2.ogg')
var/list/femalescreamsounds = list()
- var/fluff_desc = "No description."
/datum/species/synth
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_silicon.ogg')
- fluff_desc = "An advanced model of IPCs, made not only to replicate humanoid behavior but also humanoid appearance. Although they were originally built to be humanlike, they come in various \"species\", and, of course, suffer under the same prejudices of other synthetics."
/datum/species/robotic
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_silicon.ogg')
- fluff_desc = "IPCs were originally manufactured by NanoTrasen to cheaply replace humanoid workers. This backfired, as IPCs started to revolt and demand human rights throughout various protests, their degrees of violence varying - To this day, IPCs suffer with a lot of prejudice for being considered lesser than organics and a tool to replace them, even if they did win many of the rights of other sapients."
/datum/species/android
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_silicon.ogg')
- fluff_desc = "Androids are simply put, fully augmented humans. Many of them did it for the sake of near-immortality, or just because of rampant technophilia. As such, most of them are extremist transhumanists, and due to the cost of being augmented most of them are of higher class."
/datum/species/lizard
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_lizard.ogg')
- fluff_desc = "Lizardperson is an umbrella term for reptile-like sapient species. It is common for on-station lizardpeople to be civilized ashwalkers, but this is not true for all of them, as reptile-like species come from all sectors of space."
/datum/species/skeleton
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_skeleton.ogg')
- fluff_desc = "The bones inside of you, unleashed! Skeletons are animated piles of bones that walk around and chatter about. Nobody knows how or why these beings exist, or how they survive without any internal organs to speak of. ACK ACK."
/datum/species/fly
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_moth.ogg')
- fluff_desc = "Flypeople are at their most common genetically damaged sapients, who suffered extreme changes to their biology because of botched teletransportation technology. Some of them are however, simply variations of insectoids."
/datum/species/moth
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_moth.ogg')
- fluff_desc = "Mothpeople are a variant of Insectoids, and are extremely similar in biology and overall appearance, but they most commonly resemble the moths found on old human Earth."
/datum/species/snail
- femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
+ femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
/datum/species/human
femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
- fluff_desc = "Homo Sapiens Sapiens - Humans. The dominant species in the galaxy, Humanity originated from the Sol system and have quickly spread their race across the stars in the form of the vast, extraordinarily powerful Solar Federation star-state. They are the commanding species of NanoTrasen and the Solar Federation, and benefit from the highest social and economical status on both of them. While most Humans have since become welcoming of their alien comrades, they encompass a wide variety of cultures and creeds; no one Human is exactly alike."
-
-/datum/species/human/felinid
- fluff_desc = "Felinid is simply a popular name for genemodded humans with animal-like features, most commonly resembling that of a house cat."
/datum/species/dullahan
femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
- fluff_desc = "Not much is known about the mysterious dullahan, but they sure know how to make someone lose their mind."
/datum/species/ethereal
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_skeleton.ogg')
/datum/species/dwarf
femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
- fluff_desc = "The result of genetic modification for use in colonization efforts, Dwarves are extremely distant relatives of Humans. Originally made for planets with extreme gravity, Dwarves are much more bulky and short in their physiology; along with various other changes, the most unusual outcome was their biological dependence on alcohol to survive. If a Dwarf goes too long without alcohol, they will suffer similar effects to extreme dehydration in humans, eventually culminating in death."
/datum/species/mammal
femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
- fluff_desc = "Anthropomorph is an umbrella term used to describe the vast majority of sapient species one might encounter within the galaxy. They can take almost any form, and can be found all across the stars."
/datum/species/jelly
screamsounds = list('modular_skyrat/modules/emotes/sound/emotes/jelly_scream.ogg')
- fluff_desc = "Slimepeople are by and large the results of experimentation on various slime entities in control of various organizations, chief of which being Nanotrasen and their Xenobiological Research Department. While a vast majority of Slimepeople are the result of this experimentation, there exists many gel-like alien species in galaxy, along with those resultant from consumer-grade Nanotrasen brand Slime-Hybrid genemods."
/datum/species/plasmaman
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_skeleton.ogg')
- fluff_desc = "Plasmamen are the result of the catastrophic, long-term fusion of standard organic physiology with liquid and airborne pools of high-density plasma extract. The changes resulting from this fusion often times leave no trace of the victims original biology or species, turning them into an entirely plasma-based lifeform. Plasmamen are extremely reactive with oxygenated environments, requiring specialized environment suits to survive in such conditions. While most Plasmamen are employed by Nanotrasen, there are known to be pockets of plasma civilization where environmental conditions allow for at the very least tentative existence without the need of outside support."
/datum/species/pod
femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
- fluff_desc = "Podpeople are a race of sapient humanoid plants, oftentimes the result of genetic experimentation or botanical research gone awry. While most podpeople within Nanotrasen-controlled space are the result of experimental revival techniques involving a species of large cabbage, plant-based lifeforms can take a wide variety of shapes and sizes within the galaxy."
/datum/species/shadow
femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
- fluff_desc = "Shadowpeople are by and large, mostly unknown. Their origins are a mystery to almost all of civilized space - and with mystery, comes myths. The most popular of these myths is that shadowpeople were once a religious sect of ashlanders on lavaland, who lived in harmony with the dark forces who controlled the underground of the planet. One day, however it may have happened, that these people angered the dark gods of the molten hellscape, whom cursed them to forever live in eternal darkness, lest their forms waste away to the ash they had been born from. Most shadowpeople suffer extreme prejudice, as rumors are largely spread around the frontier about shadowpeople with bladelike appendages that live in the darkness, waiting to prey on the blood of the innocent and to curse everything with unending darkness."
/datum/species/robotic/synthliz
screamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_silicon.ogg')
- fluff_desc = "Synthetic Lizardpeople are a variant of IPC, much more advanced in construction. Although benefitting from higher production quality and improved internal systems, they still suffer from all of the original problems that being a synthetic humanoid comes with."
/datum/species/vampire
femalescreamsounds = list('modular_skyrat/modules/emotes/sound/voice/scream_f1.ogg', 'modular_skyrat/modules/emotes/sound/voice/scream_f2.ogg')
- fluff_desc = "Vampires are humans suffering from some form of affliction outside the realm of Science. Their metabolic systems are only capable of processing blood, which they require to sustain themselves."
/datum/species/vox
screamsounds = list('modular_skyrat/modules/emotes/sound/emotes/voxscream.ogg')
- fluff_desc = "Vox are an avian-like species found mostly in the frontier of civilized space or some distance outside of it. Their original culture and planets are long lost to history, replaced nowadays by roaming bands of raiders, traders, and refugees seeking a place to call home. Many reject them and despise them, on account of their reputation as violent pirates and slavers, as well as their... peculiar biology. Vox require pure N2 gas to breathe."
/datum/species/xeno
screamsounds = list('sound/voice/hiss6.ogg')
- fluff_desc = "Xenomorph hybrids were initially the result of faulty genetic experimentation with xenos by NanoTrasen researchers, but since then genemods for \"xenomorphication\" have become very popular among xenophilics. Although widely believed that they share some sort of affinity with normal xenomorphs, this is simply untrue - Xenomorphs are savage, and will ravage xenohybrids without any qualms."
/datum/species/zombie
screamsounds = list('modular_skyrat/modules/emotes/sound/emotes/zombie_scream.ogg')
- fluff_desc = "Zombies are the result of an as of yet largely unknown jailbroken Nanomachine software program, which overload the body by using natural metabolic and cardiovascular systems to constantly replicate themselves within a host. Hosts are extremely aggressive on account of neurological changes imposed by the nanomachines, driven to spread their affliction to anyone who isn't infected. While sapient zombies do exist, able to regulate their nanomachines to be nonlethal and overall benign, they still suffer heavy prejudice on account of their origin."
/datum/species/tajaran
screamsounds = list('modular_skyrat/modules/emotes/sound/emotes/cat_scream.ogg')
diff --git a/tgstation.dme b/tgstation.dme
index e09ae7e92ed..4e03560ac91 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -3322,6 +3322,7 @@
#include "modular_skyrat\master_files\code\datums\traits\good.dm"
#include "modular_skyrat\master_files\code\datums\traits\negative.dm"
#include "modular_skyrat\master_files\code\datums\traits\neutral.dm"
+#include "modular_skyrat\master_files\code\game\objects\ghost_role_spawners.dm"
#include "modular_skyrat\master_files\code\game\objects\items\oxygen_candle.dm"
#include "modular_skyrat\master_files\code\game\objects\items\devices\radio\encryption_key.dm"
#include "modular_skyrat\master_files\code\game\objects\items\devices\radio\headset.dm"