From 7bb2f0b96ce1b926a4abfabc2071838b93516db7 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Sat, 26 Feb 2022 21:04:34 -0600 Subject: [PATCH] De-hardcodes the species preference pages, deleting the species pages and generating them in constant data on the DM side instead (#65140) --- code/__DEFINES/DNA.dm | 16 + code/modules/client/preferences/species.dm | 32 +- code/modules/language/language_holder.dm | 5 +- .../mob/living/carbon/human/species.dm | 379 +++++++++++++++++- .../carbon/human/species_types/dullahan.dm | 43 ++ .../carbon/human/species_types/ethereal.dm | 56 ++- .../carbon/human/species_types/felinid.dm | 47 +++ .../carbon/human/species_types/flypeople.dm | 55 +++ .../carbon/human/species_types/golems.dm | 57 +++ .../carbon/human/species_types/humans.dm | 73 +++- .../carbon/human/species_types/jellypeople.dm | 19 + .../human/species_types/lizardpeople.dm | 49 ++- .../carbon/human/species_types/monkeys.dm | 106 ++++- .../carbon/human/species_types/mothmen.dm | 55 +++ .../carbon/human/species_types/mushpeople.dm | 1 + .../carbon/human/species_types/plasmamen.dm | 81 +++- .../carbon/human/species_types/podpeople.dm | 1 + .../human/species_types/shadowpeople.dm | 50 +++ .../carbon/human/species_types/skeletons.dm | 12 + .../carbon/human/species_types/vampire.dm | 71 ++++ .../carbon/human/species_types/zombies.dm | 30 +- code/modules/unit_tests/_unit_tests.dm | 1 + code/modules/unit_tests/preference_species.dm | 33 ++ .../PreferencesMenu/SpeciesPage.tsx | 141 ++++--- .../tgui/interfaces/PreferencesMenu/data.ts | 27 +- .../preferences/species/base.ts | 33 -- .../preferences/species/cloth_golem.ts | 36 -- .../preferences/species/dullahan.ts | 29 -- .../preferences/species/ethereal.ts | 64 --- .../preferences/species/felinid.ts | 28 -- .../preferences/species/fly.ts | 41 -- .../preferences/species/human.ts | 30 -- .../preferences/species/lizard.ts | 32 -- .../preferences/species/moth.ts | 38 -- .../preferences/species/plasmaman.ts | 71 ---- .../preferences/species/shadow.ts | 35 -- .../preferences/species/skeleton.ts | 33 -- .../preferences/species/vampire.ts | 41 -- .../preferences/species/zombie.ts | 45 --- 39 files changed, 1303 insertions(+), 693 deletions(-) create mode 100644 code/modules/unit_tests/preference_species.dm delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/base.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/cloth_golem.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/dullahan.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/ethereal.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/felinid.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/fly.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/human.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/lizard.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/moth.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/plasmaman.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/shadow.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/skeleton.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/vampire.ts delete mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/species/zombie.ts diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 2f3f753c931..a3301e392e9 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -242,3 +242,19 @@ GLOBAL_LIST_INIT(organ_process_order, list( #define SPECIES_GOLEM_BONE "bone_golem" #define SPECIES_GOLEM_SNOW "snow_golem" #define SPECIES_GOLEM_HYDROGEN "metallic_hydrogen_golem" + +// Defines for used in creating "perks" for the species preference pages. +/// A key that designates UI icon displayed on the perk. +#define SPECIES_PERK_ICON "ui_icon" +/// A key that designates the name of the perk. +#define SPECIES_PERK_NAME "name" +/// A key that designates the description of the perk. +#define SPECIES_PERK_DESC "description" +/// A key that designates what type of perk it is (see below). +#define SPECIES_PERK_TYPE "perk_type" + +// The possible types each perk can be. +// Positive perks are shown in green, negative in red, and neutral in grey. +#define SPECIES_POSITIVE_PERK "positive" +#define SPECIES_NEGATIVE_PERK "negative" +#define SPECIES_NEUTRAL_PERK "neutral" diff --git a/code/modules/client/preferences/species.dm b/code/modules/client/preferences/species.dm index a854a9e703c..2ad93c3b14b 100644 --- a/code/modules/client/preferences/species.dm +++ b/code/modules/client/preferences/species.dm @@ -32,29 +32,21 @@ /datum/preference/choiced/species/compile_constant_data() var/list/data = list() - var/list/food_flags = FOOD_FLAGS - for (var/species_id in get_selectable_species()) var/species_type = GLOB.species_list[species_id] - var/datum/species/species = new species_type + var/datum/species/species = new species_type() - var/list/diet = list() + data[species_id] = list() + data[species_id]["name"] = species.name + data[species_id]["desc"] = species.get_species_description() + data[species_id]["lore"] = species.get_species_lore() + data[species_id]["icon"] = sanitize_css_class_name(species.name) + data[species_id]["use_skintones"] = species.use_skintones + data[species_id]["sexes"] = species.sexes + data[species_id]["enabled_features"] = species.get_features() + data[species_id]["perks"] = species.get_species_perks() + data[species_id]["diet"] = species.get_species_diet() - if (!(TRAIT_NOHUNGER in species.inherent_traits)) - diet = list( - "liked_food" = bitfield_to_list(species.liked_food, food_flags), - "disliked_food" = bitfield_to_list(species.disliked_food, food_flags), - "toxic_food" = bitfield_to_list(species.toxic_food, food_flags), - ) - - data[species_id] = list( - "name" = species.name, - "icon" = sanitize_css_class_name(species.name), - - "use_skintones" = species.use_skintones, - "sexes" = species.sexes, - - "enabled_features" = species.get_features(), - ) + diet + qdel(species) return data diff --git a/code/modules/language/language_holder.dm b/code/modules/language/language_holder.dm index 006178b6604..601c4a93035 100644 --- a/code/modules/language/language_holder.dm +++ b/code/modules/language/language_holder.dm @@ -61,7 +61,10 @@ Key procs var/datum/mind/M = owner if(M.current) update_atom_languages(M.current) - get_selected_language() + + // If we have an owner, we'll set a default selected language + if(owner) + get_selected_language() /datum/language_holder/Destroy() QDEL_NULL(language_menu) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 559ac0a62f8..654d654eea5 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -19,6 +19,9 @@ GLOBAL_LIST_EMPTY(features_by_species) var/limbs_id ///This is the fluff name. They are displayed on health analyzers and in the character setup menu. Leave them generic for other servers to customize. var/name + /// The formatting of the name of the species in plural context. Defaults to "[name]\s" if unset. + /// Ex "[Plasmamen] are weak", "[Mothmen] are strong", "[Lizardpeople] don't like", "[Golems] hate" + var/plural_form // Default color. If mutant colors are disabled, this is the color that will be used by that race. var/default_color = "#FFFFFF" @@ -36,7 +39,7 @@ GLOBAL_LIST_EMPTY(features_by_species) ///Does the species use skintones or not? As of now only used by humans. var/use_skintones = FALSE ///If your race bleeds something other than bog standard blood, change this to reagent id. For example, ethereals bleed liquid electricity. - var/exotic_blood = "" + var/datum/reagent/exotic_blood ///If your race uses a non standard bloodtype (A+, O-, AB-, etc). For example, lizards have L type blood. var/exotic_bloodtype = "" ///What the species drops when gibbed by a gibber machine. @@ -226,11 +229,14 @@ GLOBAL_LIST_EMPTY(features_by_species) /datum/species/New() - if(!limbs_id) //if we havent set a limbs id to use, just use our own id limbs_id = id wings_icons = string_list(wings_icons) - ..() + + if(!plural_form) + plural_form = "[name]\s" + + return ..() /// Gets a list of all species available to choose in roundstart. /proc/get_selectable_species() @@ -2185,3 +2191,370 @@ GLOBAL_LIST_EMPTY(features_by_species) */ /datum/species/proc/on_owner_login(mob/living/carbon/human/owner) return + +/** + * Gets a short description for the specices. Should be relatively succinct. + * Used in the preference menu. + * + * Returns a string. + */ +/datum/species/proc/get_species_description() + SHOULD_CALL_PARENT(FALSE) + + stack_trace("Species [name] ([type]) did not have a description set, and is a selectable roundstart race! Override get_species_description.") + return "No species description set, file a bug report!" + +/** + * Gets the lore behind the type of species. Can be long. + * Used in the preference menu. + * + * Returns a list of strings. + * Between each entry in the list, a newline will be inserted, for formatting. + */ +/datum/species/proc/get_species_lore() + SHOULD_CALL_PARENT(FALSE) + RETURN_TYPE(/list) + + stack_trace("Species [name] ([type]) did not have lore set, and is a selectable roundstart race! Override get_species_lore.") + return list("No species lore set, file a bug report!") + +/** + * Translate the species liked foods from bitfields into strings + * and returns it in the form of an associated list. + * + * Returns a list, or null if they have no diet. + */ +/datum/species/proc/get_species_diet() + if(TRAIT_NOHUNGER in inherent_traits) + return null + + var/list/food_flags = FOOD_FLAGS + + return list( + "liked_food" = bitfield_to_list(liked_food, food_flags), + "disliked_food" = bitfield_to_list(disliked_food, food_flags), + "toxic_food" = bitfield_to_list(toxic_food, food_flags), + ) + +/** + * Generates a list of "perks" related to this species + * (Postives, neutrals, and negatives) + * in the format of a list of lists. + * Used in the preference menu. + * + * "Perk" format is as followed: + * list( + * SPECIES_PERK_TYPE = type of perk (postiive, negative, neutral - use the defines) + * SPECIES_PERK_ICON = icon shown within the UI + * SPECIES_PERK_NAME = name of the perk on hover + * SPECIES_PERK_DESC = description of the perk on hover + * ) + * + * Returns a list of lists. + * The outer list is an assoc list of [perk type]s to a list of perks. + * The innter list is a list of perks. Can be empty, but won't be null. + */ +/datum/species/proc/get_species_perks() + var/list/species_perks = list() + + // Let us get every perk we can concieve of in one big list. + // The order these are called (kind of) matters. + // Species unique perks first, as they're more important than genetic perks, + // and language perk last, as it comes at the end of the perks list + species_perks += create_pref_unique_perks() + species_perks += create_pref_blood_perks() + species_perks += create_pref_combat_perks() + species_perks += create_pref_damage_perks() + species_perks += create_pref_temperature_perks() + species_perks += create_pref_traits_perks() + species_perks += create_pref_biotypes_perks() + species_perks += create_pref_language_perk() + + // Some overrides may return `null`, prevent those from jamming up the list. + list_clear_nulls(species_perks) + + // Now let's sort them out for cleanliness and sanity + var/list/perks_to_return = list( + SPECIES_POSITIVE_PERK = list(), + SPECIES_NEUTRAL_PERK = list(), + SPECIES_NEGATIVE_PERK = list(), + ) + + for(var/list/perk as anything in species_perks) + var/perk_type = perk[SPECIES_PERK_TYPE] + // If we find a perk that isn't postiive, negative, or neutral, + // it's a bad entry - don't add it to our list. Throw a stack trace and skip it instead. + if(isnull(perks_to_return[perk_type])) + stack_trace("Invalid species perk ([perk[SPECIES_PERK_NAME]]) found for species [name]. \ + The type should be positive, negative, or neutral. (Got: [perk_type])") + continue + + perks_to_return[perk_type] += list(perk) + + return perks_to_return + +/** + * Used to add any species specific perks to the perk list. + * + * Returns null by default. When overriding, return a list of perks. + */ +/datum/species/proc/create_pref_unique_perks() + return null + +/** + * Adds adds any perks related to combat. + * For example, the damage type of their punches. + * + * Returns a list containing perks, or an empty list. + */ +/datum/species/proc/create_pref_combat_perks() + var/list/to_add = list() + + if(attack_type != BRUTE) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "fist-raised", + SPECIES_PERK_NAME = "Elemental Attacker", + SPECIES_PERK_DESC = "[plural_form] deal [attack_type] damage with their punches instead of brute.", + )) + + return to_add + +/** + * Adds adds any perks related to sustaining damage. + * For example, brute damage vulnerability, or fire damage resistance. + * + * Returns a list containing perks, or an empty list. + */ +/datum/species/proc/create_pref_damage_perks() + var/list/to_add = list() + + // Brute related + if(brutemod > 1) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "band-aid", + SPECIES_PERK_NAME = "Brutal Weakness", + SPECIES_PERK_DESC = "[plural_form] are weak to brute damage.", + )) + + if(brutemod < 1) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "shield-alt", + SPECIES_PERK_NAME = "Brutal Resilience", + SPECIES_PERK_DESC = "[plural_form] are resilient to bruising and brute damage.", + )) + + // Burn related + if(burnmod > 1) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "burn", + SPECIES_PERK_NAME = "Fire Weakness", + SPECIES_PERK_DESC = "[plural_form] are weak to fire and burn damage.", + )) + + if(burnmod < 1) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "shield-alt", + SPECIES_PERK_NAME = "Fire Resilience", + SPECIES_PERK_DESC = "[plural_form] are resilient to flames, and burn damage.", + )) + + // Shock damage + if(siemens_coeff > 1) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "bolt", + SPECIES_PERK_NAME = "Shock Vulnerability", + SPECIES_PERK_DESC = "[plural_form] are vulnerable to being shocked.", + )) + + if(siemens_coeff < 1) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "shield-alt", + SPECIES_PERK_NAME = "Shock Resilience", + SPECIES_PERK_DESC = "[plural_form] are resilient to being shocked.", + )) + + return to_add + +/** + * Adds adds any perks related to how the species deals with temperature. + * + * Returns a list containing perks, or an empty list. + */ +/datum/species/proc/create_pref_temperature_perks() + var/list/to_add = list() + + // Hot temperature tolerance + if(heatmod > 1 || bodytemp_heat_damage_limit < BODYTEMP_HEAT_DAMAGE_LIMIT) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "temperature-high", + SPECIES_PERK_NAME = "Heat Vulnerability", + SPECIES_PERK_DESC = "[plural_form] are vulnerable to high temperatures.", + )) + + if(heatmod < 1 || bodytemp_heat_damage_limit > BODYTEMP_HEAT_DAMAGE_LIMIT) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "thermometer-empty", + SPECIES_PERK_NAME = "Heat Resilience", + SPECIES_PERK_DESC = "[plural_form] are resilient to hotter environments.", + )) + + // Cold temperature tolerance + if(coldmod > 1 || bodytemp_cold_damage_limit > BODYTEMP_COLD_DAMAGE_LIMIT) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "temperature-low", + SPECIES_PERK_NAME = "Cold Vulnerability", + SPECIES_PERK_DESC = "[plural_form] are vulnerable to cold temperatures.", + )) + + if(coldmod < 1 || bodytemp_cold_damage_limit < BODYTEMP_COLD_DAMAGE_LIMIT) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "thermometer-empty", + SPECIES_PERK_NAME = "Cold Resilience", + SPECIES_PERK_DESC = "[plural_form] are resilient to colder environments.", + )) + + return to_add + +/** + * Adds adds any perks related to the species' blood (or lack thereof). + * + * Returns a list containing perks, or an empty list. + */ +/datum/species/proc/create_pref_blood_perks() + var/list/to_add = list() + + // NOBLOOD takes priority by default + if(NOBLOOD in species_traits) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "tint-slash", + SPECIES_PERK_NAME = "Bloodletted", + SPECIES_PERK_DESC = "[plural_form] do not have blood.", + )) + + // Otherwise, check if their exotic blood is a valid typepath + else if(ispath(exotic_blood)) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "tint", + SPECIES_PERK_NAME = initial(exotic_blood.name), + SPECIES_PERK_DESC = "[name] blood is [initial(exotic_blood.name)], which can make recieving medical treatment harder.", + )) + + // Otherwise otherwise, see if they have an exotic bloodtype set + else if(exotic_bloodtype) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "tint", + SPECIES_PERK_NAME = "Exotic Blood", + SPECIES_PERK_DESC = "[plural_form] have \"[exotic_bloodtype]\" type blood, which can make recieving medical treatment harder.", + )) + + return to_add + +/** + * Adds adds any perks related to the species' inherent_traits list. + * + * Returns a list containing perks, or an empty list. + */ +/datum/species/proc/create_pref_traits_perks() + var/list/to_add = list() + + if(TRAIT_LIMBATTACHMENT in inherent_traits) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "user-plus", + SPECIES_PERK_NAME = "Limbs Easily Reattached", + SPECIES_PERK_DESC = "[plural_form] limbs are easily readded, and as such do not \ + require surgery to restore. Simply pick it up and pop it back in, champ!", + )) + + if(TRAIT_EASYDISMEMBER in inherent_traits) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "user-times", + SPECIES_PERK_NAME = "Limbs Easily Dismembered", + SPECIES_PERK_DESC = "[plural_form] limbs are not secured well, and as such they are easily dismembered.", + )) + + if(TRAIT_EASILY_WOUNDED in inherent_traits) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "user-times", + SPECIES_PERK_NAME = "Easily Wounded", + SPECIES_PERK_DESC = "[plural_form] skin is very weak and fragile. They are much easier to apply serious wounds to.", + )) + + if(TRAIT_TOXINLOVER in inherent_traits) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "syringe", + SPECIES_PERK_NAME = "Toxins Lover", + SPECIES_PERK_DESC = "Toxins damage dealt to [plural_form] are reversed - healing toxins will instead cause harm, and \ + causing toxins will instead cause healing. Be careful around purging chemicals!", + )) + + return to_add + +/** + * Adds adds any perks related to the species' inherent_biotypes flags. + * + * Returns a list containing perks, or an empty list. + */ +/datum/species/proc/create_pref_biotypes_perks() + var/list/to_add = list() + + if(inherent_biotypes & MOB_UNDEAD) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "skull", + SPECIES_PERK_NAME = "Undead", + SPECIES_PERK_DESC = "[plural_form] are of the undead! The undead do not have the need to eat or breathe, and \ + most viruses will not be able to infect a walking corpse. Their worries mostly stop at remaining in one piece, really.", + )) + + return to_add + +/** + * Adds in a language perk based on all the languages the species + * can speak by default (according to their language holder). + * + * Returns a list containing perks, or an empty list. + */ +/datum/species/proc/create_pref_language_perk() + var/list/to_add = list() + + // Grab galactic common as a path, for comparisons + var/datum/language/common_language = /datum/language/common + + // Now let's find all the languages they can speak that aren't common + var/list/bonus_languages = list() + var/datum/language_holder/temp_holder = new species_language_holder() + for(var/datum/language/language_type as anything in temp_holder.spoken_languages) + if(ispath(language_type, common_language)) + continue + bonus_languages += initial(language_type.name) + + // If we have any languages we can speak: create a perk for them all + if(length(bonus_languages)) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "comment", + SPECIES_PERK_NAME = "Native Speaker", + SPECIES_PERK_DESC = "Alongside [initial(common_language.name)], [plural_form] gain the ability to speak [english_list(bonus_languages)].", + )) + + qdel(temp_holder) + + return to_add diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index fa138083f80..a9441bf52ae 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -111,6 +111,49 @@ eyes_toggle_perspective_action?.Trigger() owner_first_client_connection_handled = TRUE + +/datum/species/dullahan/get_species_description() + return "An angry spirit, hanging onto the land of the living for \ + unfinished business. Or that's what the books say. They're quite nice \ + when you get to know them." + +/datum/species/dullahan/get_species_lore() + return list( + "\"No wonder they're all so grumpy! Their hands are always full! I used to think, \ + \"Wouldn't this be cool?\" but after watching these creatures suffer from their head \ + getting dunked down disposals for the nth time, I think I'm good.\" - Captain Larry Dodd" + ) + +/datum/species/dullahan/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "horse-head", + SPECIES_PERK_NAME = "Headless and Horseless", + SPECIES_PERK_DESC = "Dullahans must lug their head around in their arms. While \ + many creative uses can come out of your head being independent of your \ + body, Dullahans will find it mostly a pain.", + )) + + return to_add + +// There isn't a "Minor Undead" biotype, so we have to explain it in an override (see: vampires) +/datum/species/dullahan/create_pref_biotypes_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "skull", + SPECIES_PERK_NAME = "Minor Undead", + SPECIES_PERK_DESC = "[name] are minor undead. \ + Minor undead enjoy some of the perks of being dead, like \ + not needing to breathe or eat, but do not get many of the \ + environmental immunities involved with being fully undead.", + )) + + return to_add + /obj/item/organ/brain/dullahan decoy_override = TRUE organ_flags = 0 diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index bed538f2590..add9c4ed0ce 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -27,6 +27,7 @@ bodytemp_cold_damage_limit = (T20C - 10) // about 10c hair_color = "fixedmutcolor" hair_alpha = 140 + var/current_color var/EMPeffect = FALSE var/emageffect = FALSE @@ -38,6 +39,8 @@ var/static/b2 = 149 var/obj/effect/dummy/lighting_obj/ethereal_light + + /datum/species/ethereal/Destroy(force) if(ethereal_light) QDEL_NULL(ethereal_light) @@ -149,6 +152,53 @@ return features /datum/species/ethereal/get_scream_sound(mob/living/carbon/human/ethereal) - return pick('sound/voice/ethereal/ethereal_scream_1.ogg', - 'sound/voice/ethereal/ethereal_scream_2.ogg', - 'sound/voice/ethereal/ethereal_scream_3.ogg') + return pick( + 'sound/voice/ethereal/ethereal_scream_1.ogg', + 'sound/voice/ethereal/ethereal_scream_2.ogg', + 'sound/voice/ethereal/ethereal_scream_3.ogg', + ) + +/datum/species/ethereal/get_species_description() + return "Coming from the planet of Sprout, the theocratic ethereals are \ + separated socially by caste, and espouse a dogma of aiding the weak and \ + downtrodden." + +/datum/species/ethereal/get_species_lore() + return list( + "Ethereals are a species native to the planet Sprout. \ + When they were originally discovered, they were at a medieval level of technological progression, \ + but due to their natural acclimation with electricity, they felt easy among the large NanoTrasen installations.", + ) + +/datum/species/ethereal/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "bolt", + SPECIES_PERK_NAME = "Shockingly Tasty", + SPECIES_PERK_DESC = "Ethereals can feed on electricity from APCs, and do not otherwise need to eat.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "lightbulb", + SPECIES_PERK_NAME = "Disco Ball", + SPECIES_PERK_DESC = "Ethereals passively generate their own light.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "gem", + SPECIES_PERK_NAME = "Crystal Core", + SPECIES_PERK_DESC = "The Ethereal's heart will encase them in crystal should they die, returning them to life after a time - \ + at the cost of a permanent brain trauma.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "biohazard", + SPECIES_PERK_NAME = "Starving Artist", + SPECIES_PERK_DESC = "Ethereals take toxin damage while starving.", + ), + ) + + return to_add diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index c40a5f8d3ae..632c424ecd2 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -141,3 +141,50 @@ if (cat_ears) cat_ears.color = human.hair_color human.update_body() + +/datum/species/human/felinid/get_species_description() + return "Felinids are one of the many types of bespoke genetic \ + modifications to come of humanity's mastery of genetic science, and are \ + also one of the most common. Meow?" + +/datum/species/human/felinid/get_species_lore() + return list( + "Bio-engineering at its felinest, Felinids are the peak example of humanity's mastery of genetic code. \ + One of many \"Animalid\" variants, Felinids are the most popular and common, as well as one of the \ + biggest points of contention in genetic-modification.", + + "Body modders were eager to splice human and feline DNA in search of the holy trifecta: ears, eyes, and tail. \ + These traits were in high demand, with the corresponding side effects of vocal and neurochemical changes being seen as a minor inconvenience.", + + "Sadly for the Felinids, they were not minor inconveniences. Shunned as subhuman and monstrous by many, Felinids (and other Animalids) \ + sought their greener pastures out in the colonies, cloistering in communities of their own kind. \ + As a result, outer Human space has a high Animalid population.", + ) + +// Felinids are subtypes of humans. +// This shouldn't call parent or we'll get a buncha human related perks (though it doesn't have a reason to). +/datum/species/human/felinid/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "grin-tongue", + SPECIES_PERK_NAME = "Grooming", + SPECIES_PERK_DESC = "Felinids can lick wounds to reduce bleeding.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "assistive-listening-systems", + SPECIES_PERK_NAME = "Sensitive Hearing", + SPECIES_PERK_DESC = "Felinids are more sensitive to loud sounds, such as flashbangs.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "shower", + SPECIES_PERK_NAME = "Hydrophobia", + SPECIES_PERK_DESC = "Felinids don't like getting soaked with water.", + ), + ) + + return to_add diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm index 8221228ff4b..d7bd542c795 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -1,5 +1,6 @@ /datum/species/fly name = "Flyperson" + plural_form = "Flypeople" id = SPECIES_FLY say_mod = "buzzes" species_traits = list(HAS_FLESH, HAS_BONE, TRAIT_ANTENNAE) @@ -38,6 +39,60 @@ return 30 //Flyswatters deal 30x damage to flypeople. return 1 +/datum/species/fly/get_species_description() + return "With no official documentation or knowledge of the origin of \ + this species, they remain a mystery to most. Any and all rumours among \ + Nanotrasen staff regarding flypeople are often quickly silenced by high \ + ranking staff or officials." + +/datum/species/fly/get_species_lore() + return list( + "Flypeople are a curious species with a striking resemblance to the insect order of Diptera, \ + commonly known as flies. With no publically known origin, flypeople are rumored to be a side effect of bluespace travel, \ + despite statements from Nanotrasen officials.", + + "Little is known about the origins of this race, \ + however they posess the ability to communicate with giant spiders, originally discovered in the Australicus sector \ + and now a common occurence in black markets as a result of a breakthrough in syndicate bioweapon research.", + + "Flypeople are often feared or avoided among other species, their appearance often described as unclean or frightening in some cases, \ + and their eating habits even more so with an insufferable accent to top it off.", + ) + +/datum/species/fly/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "grin-tongue", + SPECIES_PERK_NAME = "Uncanny Digestive System", + SPECIES_PERK_DESC = "Flypeople regurgitate their stomach contents and drink it \ + off the floor to eat and drink with little care for taste, favoring gross foods.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "fist-raised", + SPECIES_PERK_NAME = "Insectoid Biology", + SPECIES_PERK_DESC = "Fly swatters will deal significantly higher amounts of damage to a Flyperson.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "sun", + SPECIES_PERK_NAME = "Radial Eyesight", + SPECIES_PERK_DESC = "Flypeople can be flashed from all angles.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "briefcase-medical", + SPECIES_PERK_NAME = "Weird Organs", + SPECIES_PERK_DESC = "Flypeople take specialized medical knowledge to be \ + treated. Their organs are disfigured and organ manipulation can be interesting...", + ), + ) + + return to_add + /obj/item/organ/heart/fly desc = "You have no idea what the hell this is, or how it manages to keep something alive in any capacity." diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index f7e2d36d5f1..eff7dbc2353 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -59,6 +59,21 @@ var/golem_name = "[prefix] [golem_surname]" return golem_name +/datum/species/golem/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "gem", + SPECIES_PERK_NAME = "Lithoid", + SPECIES_PERK_DESC = "Lithoids are creatures made out of elements instead of \ + blood and flesh. Because of this, they're generally stronger, slower, \ + and mostly immune to environmental dangers and dangers to their health, \ + such as viruses and dismemberment.", + )) + + return to_add + /datum/species/golem/random name = "Random Golem" changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN @@ -802,6 +817,48 @@ new /obj/structure/cloth_pile(get_turf(H), H) ..() +/datum/species/golem/cloth/get_species_description() + return "A wrapped up Mummy! They descend upon Space Station Thirteen every year to spook the crew! \"Return the slab!\"" + +/datum/species/golem/cloth/get_species_lore() + return list( + "Mummies are very self conscious. They're shaped weird, they walk slow, and worst of all, \ + they're considered the laziest halloween costume. But that's not even true, they say.", + + "Making a mummy costume may be easy, but making a CONVINCING mummy costume requires \ + things like proper fabric and purposeful staining to achieve the look. Which is FAR from easy. Gosh.", + ) + +// Calls parent, as Golems have a species-wide perk we care about. +/datum/species/golem/cloth/create_pref_unique_perks() + var/list/to_add = ..() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "recycle", + SPECIES_PERK_NAME = "Reformation", + SPECIES_PERK_DESC = "A boon quite similar to Ethereals, Mummies collapse into \ + a pile of bandages after they die. If left alone, they will reform back \ + into themselves. The bandages themselves are very vulnerable to fire.", + )) + + return to_add + +// Override to add a perk elaborating on just how dangerous fire is. +/datum/species/golem/cloth/create_pref_temperature_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "fire-alt", + SPECIES_PERK_NAME = "Incredibly Flammable", + SPECIES_PERK_DESC = "Mummies are made entirely of cloth, which makes them \ + very vulnerable to fire. They will not reform if they die while on \ + fire, and they will easily catch alight. If your bandages burn to ash, you're toast!", + )) + + return to_add + /obj/structure/cloth_pile name = "pile of bandages" desc = "It emits a strange aura, as if there was still life within it..." diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index b928876b780..271bd95c5c6 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -25,14 +25,65 @@ if(human.gender == MALE) if(prob(1)) return 'sound/voice/human/wilhelm_scream.ogg' - return pick('sound/voice/human/malescream_1.ogg', - 'sound/voice/human/malescream_2.ogg', - 'sound/voice/human/malescream_3.ogg', - 'sound/voice/human/malescream_4.ogg', - 'sound/voice/human/malescream_5.ogg', - 'sound/voice/human/malescream_6.ogg') - return pick('sound/voice/human/femalescream_1.ogg', - 'sound/voice/human/femalescream_2.ogg', - 'sound/voice/human/femalescream_3.ogg', - 'sound/voice/human/femalescream_4.ogg', - 'sound/voice/human/femalescream_5.ogg') + return pick( + 'sound/voice/human/malescream_1.ogg', + 'sound/voice/human/malescream_2.ogg', + 'sound/voice/human/malescream_3.ogg', + 'sound/voice/human/malescream_4.ogg', + 'sound/voice/human/malescream_5.ogg', + 'sound/voice/human/malescream_6.ogg', + ) + + return pick( + 'sound/voice/human/femalescream_1.ogg', + 'sound/voice/human/femalescream_2.ogg', + 'sound/voice/human/femalescream_3.ogg', + 'sound/voice/human/femalescream_4.ogg', + 'sound/voice/human/femalescream_5.ogg', + ) + +/datum/species/human/get_species_description() + return "Humans are the dominant species in the known galaxy. \ + Their kind extend from old Earth to the edges of known space." + +/datum/species/human/get_species_lore() + return list( + "These primate-descended creatures, originating from the mostly harmless Earth, \ + have long-since outgrown their home and semi-benign designation. \ + The space age has taken humans out of their solar system and into the galaxy-at-large.", + + "In traditional human fashion, this near-record pace from terra firma to the final frontier spat \ + in the face of other races they now shared a stage with. \ + This included the lizards - if anyone was offended by these upstarts, it was certainly lizardkind.", + + "Humanity never managed to find the kind of peace to fully unite under one banner like other species. \ + The pencil and paper pushing of the UN bureaucrat lives on in the mosaic that is TerraGov; \ + a composite of the nation-states that still live on in human society.", + + "The human spirit of opportunity and enterprise continues on in its peak form: \ + the hypercorporation. Acting outside of TerraGov's influence, literally and figuratively, \ + hypercorporations buy the senate votes they need and establish territory far past the Earth Government's reach. \ + In hypercorporation territory company policy is law, giving new meaning to \"employee termination\".", + ) + +/datum/species/human/create_pref_unique_perks() + var/list/to_add = list() + + if(CONFIG_GET(number/default_laws) == 0) // Default lawset is set to Asimov + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "robot", + SPECIES_PERK_NAME = "Asimov Superiority", + SPECIES_PERK_DESC = "The AI and their cyborgs are, by default, subservient only \ + to humans. As a human, silicons are required to both protect and obey you.", + )) + + if(CONFIG_GET(flag/enforce_human_authority)) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "bullhorn", + SPECIES_PERK_NAME = "Chain of Command", + SPECIES_PERK_DESC = "Nanotrasen only recognizes humans for command roles, such as Captain.", + )) + + return to_add diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 6e9424404e6..b62f969d1e7 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -1,6 +1,7 @@ /datum/species/jelly // Entirely alien beings that seem to be made entirely out of gel. They have three eyes and a skeleton visible within them. name = "Jellyperson" + plural_form = "Jellypeople" id = SPECIES_JELLYPERSON default_color = "00FF90" say_mod = "chirps" @@ -75,6 +76,21 @@ qdel(consumed_limb) H.blood_volume += 20 +// Slimes have both NOBLOOD and an exotic bloodtype set, so they need to be handled uniquely here. +// They may not be roundstart but in the unlikely event they become one might as well not leave a glaring issue open. +/datum/species/jelly/create_pref_blood_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "tint", + SPECIES_PERK_NAME = "Jelly Blood", + SPECIES_PERK_DESC = "[plural_form] don't have blood, but instead have toxic [initial(exotic_blood.name)]! \ + Jelly is extremely important, as losing it will cause you to lose limbs. Having low jelly will make medical treatment very difficult.", + )) + + return to_add + /datum/action/innate/regenerate_limbs name = "Regenerate Limbs" check_flags = AB_CHECK_CONSCIOUS @@ -121,6 +137,7 @@ /datum/species/jelly/slime name = "Slimeperson" + plural_form = "Slimepeople" id = SPECIES_SLIMEPERSON default_color = "00FFFF" species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD) @@ -406,6 +423,7 @@ /datum/species/jelly/luminescent name = "Luminescent" + plural_form = null id = SPECIES_LUMINESCENT var/glow_intensity = LUMINESCENT_DEFAULT_GLOW var/obj/effect/dummy/luminescent_glow/glow @@ -588,6 +606,7 @@ /datum/species/jelly/stargazer name = "Stargazer" + plural_form = null id = SPECIES_STARGAZER /// Special "project thought" telepathy action for stargazers. var/datum/action/innate/project_thought/project_action diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 0436c96f5e3..eb693579713 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -1,6 +1,7 @@ /datum/species/lizard // Reptilian humanoids with scaled skin and tails. name = "Lizardperson" + plural_form = "Lizardfolk" id = SPECIES_LIZARD say_mod = "hisses" default_color = COLOR_VIBRANT_LIME @@ -116,9 +117,51 @@ human_mob.update_body() /datum/species/lizard/get_scream_sound(mob/living/carbon/human/lizard) - return pick('sound/voice/lizard/lizard_scream_1.ogg', - 'sound/voice/lizard/lizard_scream_2.ogg', - 'sound/voice/lizard/lizard_scream_3.ogg') + return pick( + 'sound/voice/lizard/lizard_scream_1.ogg', + 'sound/voice/lizard/lizard_scream_2.ogg', + 'sound/voice/lizard/lizard_scream_3.ogg', + ) + +/datum/species/lizard/get_species_description() + return "The militaristic Lizardpeople hail originally from Tizira, but have grown \ + throughout their centuries in the stars to possess a large spacefaring \ + empire: though now they must contend with their younger, more \ + technologically advanced Human neighbours." + +/datum/species/lizard/get_species_lore() + return list( + "The face of conspiracy theory was changed forever the day mankind met the lizards.", + + "Hailing from the arid world of Tizira, lizards were travelling the stars back when mankind was first discovering how neat trains could be. \ + However, much like the space-fable of the space-tortoise and space-hare, lizards have rejected their kin's motto of \"slow and steady\" \ + in favor of resting on their laurels and getting completely surpassed by 'bald apes', due in no small part to their lack of access to plasma.", + + "The history between lizards and humans has resulted in many conflicts that lizards ended on the losing side of, \ + with the finale being an explosive remodeling of their moon. Today's lizard-human relations are seeing the continuance of a record period of peace.", + + "Lizard culture is inherently militaristic, though the influence the military has on lizard culture \ + begins to lessen the further colonies lie from their homeworld - \ + with some distanced colonies finding themselves subsumed by the cultural practices of other species nearby.", + + "On their homeworld, lizards celebrate their 16th birthday by enrolling in a mandatory 5 year military tour of duty. \ + Roles range from combat to civil service and everything in between. As the old slogan goes: \"Your place will be found!\"", + ) + +// Override for the default temperature perks, so we can give our specific "cold blooded" perk. +/datum/species/lizard/create_pref_temperature_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "thermometer-empty", + SPECIES_PERK_NAME = "Cold-blooded", + SPECIES_PERK_DESC = "Lizardpeople have higher tolerance for hot temperatures, but lower \ + tolerance for cold temperatures. Additionally, they cannot self-regulate their body temperature - \ + they are as cold or as warm as the environment around them is. Stay warm!", + )) + + return to_add /* Lizard subspecies: ASHWALKERS diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm index a85a7d7562f..9e835ba3d80 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -12,7 +12,16 @@ meat = /obj/item/food/meat/slab/monkey allowed_animal_origin = MONKEY_BODY knife_butcher_results = list(/obj/item/food/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1) - species_traits = list(HAS_FLESH,HAS_BONE,NO_UNDERWEAR,LIPS,NOEYESPRITES,NOBLOODOVERLAY,NOTRANSSTING, NOAUGMENTS) + species_traits = list( + HAS_FLESH, + HAS_BONE, + NO_UNDERWEAR, + LIPS, + NOEYESPRITES, + NOBLOODOVERLAY, + NOTRANSSTING, + NOAUGMENTS, + ) inherent_traits = list( TRAIT_CAN_STRIP, TRAIT_VENTCRAWLER_NUDE, @@ -20,7 +29,15 @@ TRAIT_WEAK_SOUL, TRAIT_GUN_NATURAL, ) - no_equip = list(ITEM_SLOT_EARS, ITEM_SLOT_EYES, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) + no_equip = list( + ITEM_SLOT_EARS, + ITEM_SLOT_EYES, + ITEM_SLOT_OCLOTHING, + ITEM_SLOT_GLOVES, + ITEM_SLOT_FEET, + ITEM_SLOT_ICLOTHING, + ITEM_SLOT_SUITSTORE, + ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | ERT_SPAWN | SLIME_EXTRACT liked_food = MEAT | FRUIT disliked_food = CLOTH @@ -32,12 +49,13 @@ punchstunthreshold = 4 // no stun punches species_language_holder = /datum/language_holder/monkey bodypart_overides = list( - BODY_ZONE_L_ARM = /obj/item/bodypart/l_arm/monkey,\ - BODY_ZONE_R_ARM = /obj/item/bodypart/r_arm/monkey,\ - BODY_ZONE_HEAD = /obj/item/bodypart/head/monkey,\ - BODY_ZONE_L_LEG = /obj/item/bodypart/l_leg/monkey,\ - BODY_ZONE_R_LEG = /obj/item/bodypart/r_leg/monkey,\ - BODY_ZONE_CHEST = /obj/item/bodypart/chest/monkey) + BODY_ZONE_L_ARM = /obj/item/bodypart/l_arm/monkey, + BODY_ZONE_R_ARM = /obj/item/bodypart/r_arm/monkey, + BODY_ZONE_HEAD = /obj/item/bodypart/head/monkey, + BODY_ZONE_L_LEG = /obj/item/bodypart/l_leg/monkey, + BODY_ZONE_R_LEG = /obj/item/bodypart/r_leg/monkey, + BODY_ZONE_CHEST = /obj/item/bodypart/chest/monkey, + ) fire_overlay = "Monkey_burning" dust_anim = "dust-m" gib_anim = "gibbed-m" @@ -108,10 +126,68 @@ return ..() /datum/species/monkey/get_scream_sound(mob/living/carbon/human/monkey) - return pick('sound/creatures/monkey/monkey_screech_1.ogg', - 'sound/creatures/monkey/monkey_screech_2.ogg', - 'sound/creatures/monkey/monkey_screech_3.ogg', - 'sound/creatures/monkey/monkey_screech_4.ogg', - 'sound/creatures/monkey/monkey_screech_5.ogg', - 'sound/creatures/monkey/monkey_screech_6.ogg', - 'sound/creatures/monkey/monkey_screech_7.ogg') + return pick( + 'sound/creatures/monkey/monkey_screech_1.ogg', + 'sound/creatures/monkey/monkey_screech_2.ogg', + 'sound/creatures/monkey/monkey_screech_3.ogg', + 'sound/creatures/monkey/monkey_screech_4.ogg', + 'sound/creatures/monkey/monkey_screech_5.ogg', + 'sound/creatures/monkey/monkey_screech_6.ogg', + 'sound/creatures/monkey/monkey_screech_7.ogg', + ) + +/datum/species/monkey/get_species_description() + return "Monkeys are a type of primate that exist between humans and animals on the evolutionary chain. \ + Every year, on Monkey Day, Nanotrasen shows their respect for the little guys by allowing them to roam the station freely." + +/datum/species/monkey/get_species_lore() + return list( + "Monkeys are commonly used as test subjects on board Space Station Thirteen. \ + But what if... for one day... the Monkeys were allowed to be the scientists? \ + What experiments would they come up it? Would they (stereotypically) be related to bananas somehow? \ + There's only one way to find out.", + ) + +/datum/species/monkey/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "spider", + SPECIES_PERK_NAME = "Vent Crawling", + SPECIES_PERK_DESC = "Monkeys can crawl through the vent and scrubber networks while wearing no clothing. \ + Stay out of the kitchen!", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "paw", + SPECIES_PERK_NAME = "Primal Primate", + SPECIES_PERK_DESC = "Monkeys are primitive humans, and can't do most things a human can do. Computers are impossible, \ + complex machines are right out, and most clothes don't fit your smaller form.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "capsules", + SPECIES_PERK_NAME = "Mutadone Averse", + SPECIES_PERK_DESC = "Monkeys are reverted into normal humans upon being exposed to Mutadone.", + ), + ) + + return to_add + +/datum/species/monkey/create_pref_language_perk() + var/list/to_add = list() + // Holding these variables so we can grab the exact names for our perk. + var/datum/language/common_language = /datum/language/common + var/datum/language/monkey_language = /datum/language/monkey + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "comment", + SPECIES_PERK_NAME = "Primitive Tongue", + SPECIES_PERK_DESC = "You may be able to understand [initial(common_language.name)], but you can't speak it. \ + You can only speak [initial(monkey_language.name)].", + )) + + return to_add diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index 92b63ef988c..5e06277ac7e 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -1,5 +1,6 @@ /datum/species/moth name = "Mothman" + plural_form = "Mothmen" id = SPECIES_MOTH say_mod = "flutters" default_color = "00FF00" @@ -66,3 +67,57 @@ /datum/species/moth/get_scream_sound(mob/living/carbon/human/human) return 'sound/voice/moth/scream_moth.ogg' + +/datum/species/moth/get_species_description() + return "Hailing from a planet that was lost long ago, the moths travel \ + the galaxy as a nomadic people aboard a colossal fleet of ships, seeking a new homeland." + +/datum/species/moth/get_species_lore() + return list( + "Their homeworld lost to the ages, the moths live aboard the Grand Nomad Fleet. \ + Made up of what could be found, bartered, repaired, or stolen the armada is a colossal patchwork \ + built on a history of politely flagging travelers down and taking their things. Occasionally a moth \ + will decide to leave the fleet, usually to strike out for fortunes to send back home.", + + "Nomadic life produces a tight-knit culture, with moths valuing their friends, family, and vessels highly. \ + Moths are gregarious by nature and do best in communal spaces. This has served them well on the galactic stage, \ + maintaining a friendly and personable reputation even in the face of hostile encounters. \ + It seems that the galaxy has come to accept these former pirates.", + + "Surprisingly, living together in a giant fleet hasn't flattened variance in dialect and culture. \ + These differences are welcomed and encouraged within the fleet for the variety that they bring.", + ) + +/datum/species/moth/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "feather-alt", + SPECIES_PERK_NAME = "Precious Wings", + SPECIES_PERK_DESC = "Moths can fly in pressurized, zero-g environments and safely land short falls using their wings.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "tshirt", + SPECIES_PERK_NAME = "Meal Plan", + SPECIES_PERK_DESC = "Moths can eat clothes for nourishment.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "fire", + SPECIES_PERK_NAME = "Ablazed Wings", + SPECIES_PERK_DESC = "Moth wings are fragile, and can be easily burnt off.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "sun", + SPECIES_PERK_NAME = "Bright Lights", + SPECIES_PERK_DESC = "Moths need an extra layer of flash protection to protect \ + themselves, such as against security officers or when welding. Welding \ + masks will work.", + ), + ) + + return to_add diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm index 593876e17b9..08f15068520 100644 --- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm @@ -1,5 +1,6 @@ /datum/species/mush //mush mush codecuck name = "Mushroomperson" + plural_form = "Mushroompeople" id = SPECIES_MUSHROOM mutant_bodyparts = list("caps" = "Round") changesource_flags = MIRROR_BADMIN | WABBAJACK | ERT_SPAWN diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index d0e5f9164af..ac93e248a59 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -1,5 +1,6 @@ /datum/species/plasmaman name = "Plasmaman" + plural_form = "Plasmamen" id = SPECIES_PLASMAMAN say_mod = "rattles" sexes = 0 @@ -27,7 +28,6 @@ payday_modifier = 0.75 breathid = "plas" damage_overlay_type = ""//let's not show bloody wounds or burns over bones. - var/internal_fire = FALSE //If the bones themselves are burning clothes won't help you much disliked_food = FRUIT | CLOTH liked_food = VEGETABLES changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC @@ -45,6 +45,9 @@ ass_image = 'icons/ass/assplasma.png' + /// If the bones themselves are burning clothes won't help you much + var/internal_fire = FALSE + /datum/species/plasmaman/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) . = ..() C.set_safe_hunger_level() @@ -137,3 +140,79 @@ H.emote("sigh") H.reagents.remove_reagent(chem.type, chem.metabolization_rate * delta_time) return TRUE + +/datum/species/plasmaman/get_species_description() + return "Found on the Icemoon of Freyja, plasmamen consist of colonial \ + fungal organisms which together form a sentient being. In human space, \ + they're usually attached to skeletons to afford a human touch." + +/datum/species/plasmaman/get_species_lore() + return list( + "A confusing species, plasmamen are truly \"a fungus among us\". \ + What appears to be a singular being is actually a colony of millions of organisms \ + surrounding a found (or provided) skeletal structure.", + + "Originally discovered by NT when a researcher \ + fell into an open tank of liquid plasma, the previously unnoticed fungal colony overtook the body creating \ + the first \"true\" plasmaman. The process has since been streamlined via generous donations of convict corpses and plasmamen \ + have been deployed en masse throughout NT to bolster the workforce.", + + "New to the galactic stage, plasmamen are a blank slate. \ + Their appearance, generally regarded as \"ghoulish\", inspires a lot of apprehension in their crewmates. \ + It might be the whole \"flammable purple skeleton\" thing.", + + "The colonids that make up plasmamen require the plasma-rich atmosphere they evolved in. \ + Their psuedo-nervous system runs with externalized electrical impulses that immediately ignite their plasma-based bodies when oxygen is present.", + ) + +/datum/species/plasmaman/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "user-shield", + SPECIES_PERK_NAME = "Protected", + SPECIES_PERK_DESC = "Plasmamen are immune to radiation, poisons, and most diseases.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "bone", + SPECIES_PERK_NAME = "Wound Resistance", + SPECIES_PERK_DESC = "Plasmamen have higher tolerance for damage that would wound others.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "wind", + SPECIES_PERK_NAME = "Plasma Healing", + SPECIES_PERK_DESC = "Plasmamen can heal wounds by consuming plasma.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "hard-hat", + SPECIES_PERK_NAME = "Protective Helmet", + SPECIES_PERK_DESC = "Plasmamen's helmets provide them shielding from the flashes of welding, as well as an inbuilt flashlight.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "fire", + SPECIES_PERK_NAME = "Living Torch", + SPECIES_PERK_DESC = "Plasmamen instantly ignite when their body makes contact with oxygen.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "wind", + SPECIES_PERK_NAME = "Plasma Breathing", + SPECIES_PERK_DESC = "Plasmamen must breathe plasma to survive. You receive a tank when you arrive.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "briefcase-medical", + SPECIES_PERK_NAME = "Complex Biology", + SPECIES_PERK_DESC = "Plasmamen take specialized medical knowledge to be \ + treated. Do not expect speedy revival, if you are lucky enough to get \ + one at all.", + ), + ) + + return to_add diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index 3de8528fa7c..b283531f43f 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -1,6 +1,7 @@ /datum/species/pod // A mutation caused by a human being ressurected in a revival pod. These regain health in light, and begin to wither in darkness. name = "Podperson" + plural_form = "Podpeople" id = SPECIES_PODPERSON default_color = "59CE00" species_traits = list(MUTCOLORS,EYECOLOR, HAS_FLESH, HAS_BONE) diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index b822cccdda0..e1013f5c658 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -1,6 +1,7 @@ /datum/species/shadow // Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light. name = "Shadow" + plural_form = "Shadowpeople" id = SPECIES_SHADOW sexes = 0 meat = /obj/item/food/meat/slab/human/mutant/shadow @@ -32,3 +33,52 @@ if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) return TRUE return ..() + +/datum/species/shadow/get_species_description() + return "Victims of a long extinct space alien. Their flesh is a sickly \ + seethrough filament, their tangled insides in clear view. Their form \ + is a mockery of life, leaving them mostly unable to work with others under \ + normal circumstances." + +/datum/species/shadow/get_species_lore() + return list( + "Long ago, the Spinward Sector used to be inhabited by terrifying aliens aptly named \"Shadowlings\" \ + after their control over darkness, and tendancy to kidnap victims into the dark maintenance shafts. \ + Around 2558, the long campaign Nanotrasen waged against the space terrors ended with the full extinction of the Shadowlings.", + + "Victims of their kidnappings would become brainless thralls, and via surgery they could be freed from the Shadowling's control. \ + Those more unlucky would have their entire body transformed by the Shadowlings to better serve in kidnappings. \ + Unlike the brain tumors of lesser control, these greater thralls could not be reverted.", + + "With Shadowlings long gone, their will is their own again. But their bodies have not reverted, burning in exposure to light. \ + Nanotrasen has assured the victims that they are searching for a cure. No further information has been given, even years later. \ + Most shadowpeople now assume Nanotrasen has long since shelfed the project.", + ) + +/datum/species/shadow/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "moon", + SPECIES_PERK_NAME = "Shadowborn", + SPECIES_PERK_DESC = "Their skin blooms in the darkness. All kinds of damage, \ + no matter how extreme, will heal over time as long as there is no light.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "eye", + SPECIES_PERK_NAME = "Nightvision", + SPECIES_PERK_DESC = "Their eyes are adapted to the night, and can see in the dark with no problems.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "sun", + SPECIES_PERK_NAME = "Lightburn", + SPECIES_PERK_DESC = "Their flesh withers in the light. Any exposure to light is \ + incredibly painful for the shadowperson, charring their skin.", + ), + ) + + return to_add diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index db843ff535c..55af5450ef2 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -75,3 +75,15 @@ H.emote("sigh") H.reagents.remove_reagent(chem.type, chem.metabolization_rate * delta_time) return TRUE + +/datum/species/skeleton/get_species_description() + return "A rattling skeleton! They descend upon Space Station 13 \ + Every year to spook the crew! \"I've got a BONE to pick with you!\"" + +/datum/species/skeleton/get_species_lore() + return list( + "Skeletons want to be feared again! Their presence in media has been destroyed, \ + or at least that's what they firmly believe. They're always the first thing fought in an RPG, \ + they're Flanderized into pun rolling JOKES, and it's really starting to get to them. \ + You could say they're deeply RATTLED. Hah." + ) diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index d981c6f0425..88ddce6b7d1 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -75,6 +75,77 @@ return 2 //Whips deal 2x damage to vampires. Vampire killer. return 1 +/datum/species/vampire/get_species_description() + return "A classy Vampire! They descend upon Space Station Thirteen Every year to spook the crew! \"Bleeg!!\"" + +/datum/species/vampire/get_species_lore() + return list( + "Vampires are unholy beings blessed and cursed with The Thirst. \ + The Thirst requires them to feast on blood to stay alive, and in return it gives them many bonuses. \ + Because of this, Vampires have split into two clans, one that embraces their powers as a blessing and one that rejects it.", + ) + +/datum/species/vampire/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "bed", + SPECIES_PERK_NAME = "Coffin Brooding", + SPECIES_PERK_DESC = "Vampires can delay The Thirst and heal by resting in a coffin. So THAT'S why they do that!", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "book-dead", + SPECIES_PERK_NAME = "Vampire Clans", + SPECIES_PERK_DESC = "Vampires belong to one of two clans - the Inoculated, and the Outcast. The Outcast \ + don't follow many vampiric traditions, while the Inoculated are given unique names and flavor.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "cross", + SPECIES_PERK_NAME = "Against God and Nature", + SPECIES_PERK_DESC = "Almost all higher powers are disgusted by the existence of \ + Vampires, and entering the Chapel is essentially suicide. Do not do it!", + ), + ) + + return to_add + +// Vampire blood is special, so it needs to be handled with its own entry. +/datum/species/vampire/create_pref_blood_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "tint", + SPECIES_PERK_NAME = "The Thirst", + SPECIES_PERK_DESC = "In place of eating, Vampires suffer from The Thirst. \ + Thirst of what? Blood! Their tongue allows them to grab people and drink \ + their blood, and they will die if they run out. As a note, it doesn't \ + matter whose blood you drink, it will all be converted into your blood \ + type when consumed.", + )) + + return to_add + +// There isn't a "Minor Undead" biotype, so we have to explain it in an override (see: dullahans) +/datum/species/vampire/create_pref_biotypes_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "skull", + SPECIES_PERK_NAME = "Minor Undead", + SPECIES_PERK_DESC = "[name] are minor undead. \ + Minor undead enjoy some of the perks of being dead, like \ + not needing to breathe or eat, but do not get many of the \ + environmental immunities involved with being fully undead.", + )) + + return to_add + /obj/item/organ/tongue/vampire name = "vampire tongue" actions_types = list(/datum/action/item_action/organ_action/vampire) diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 92e66f0bdc5..f428a46509e 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -36,11 +36,37 @@ bodytemp_heat_damage_limit = FIRE_MINIMUM_TEMPERATURE_TO_EXIST // Take damage at fire temp bodytemp_cold_damage_limit = MINIMUM_TEMPERATURE_TO_MOVE // take damage below minimum movement temp +/// Zombies do not stabilize body temperature they are the walking dead and are cold blooded +/datum/species/zombie/body_temperature_core(mob/living/carbon/human/humi, delta_time, times_fired) + return + /datum/species/zombie/check_roundstart_eligible() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) return TRUE return ..() +/datum/species/zombie/get_species_description() + return "A rotting zombie! They descend upon Space Station Thirteen Every year to spook the crew! \"Sincerely, the Zombies!\"" + +/datum/species/zombie/get_species_lore() + return list("Zombies have long lasting beef with Botanists. Their last incident involving a lawn with defensive plants has left them very unhinged.") + +// Override for the default temperature perks, so we can establish that they don't care about temperature very much +/datum/species/zombie/create_pref_temperature_perks() + var/list/to_add = list() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "thermometer-half", + SPECIES_PERK_NAME = "No Body Temperature", + SPECIES_PERK_DESC = "Having long since departed, Zombies do not have anything \ + regulating their body temperature anymore. This means that \ + the environment decides their body temperature - which they don't mind at \ + all, until it gets a bit too hot.", + )) + + return to_add + /datum/species/zombie/infectious name = "Infectious Zombie" id = SPECIES_ZOMBIE @@ -55,10 +81,6 @@ /// The cooldown before the zombie can start regenerating COOLDOWN_DECLARE(regen_cooldown) -/// Zombies do not stabilize body temperature they are the walking dead and are cold blooded -/datum/species/zombie/body_temperature_core(mob/living/carbon/human/humi, delta_time, times_fired) - return - /datum/species/zombie/infectious/check_roundstart_eligible() return FALSE diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 7ee668382d4..f5de816e136 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -89,6 +89,7 @@ #include "outfit_sanity.dm" #include "pills.dm" #include "plantgrowth_tests.dm" +#include "preference_species.dm" #include "preferences.dm" #include "projectiles.dm" #include "quirks.dm" diff --git a/code/modules/unit_tests/preference_species.dm b/code/modules/unit_tests/preference_species.dm new file mode 100644 index 00000000000..f06c894a5f8 --- /dev/null +++ b/code/modules/unit_tests/preference_species.dm @@ -0,0 +1,33 @@ + +/** + * Checks that all enabled roundstart species + * selectable within the preferences menu + * have their info / page setup correctly. + */ +/datum/unit_test/preference_species + +/datum/unit_test/preference_species/Run() + + // Go though all selectable species to see if they have their page setup correctly. + for(var/species_id in get_selectable_species()) + + var/species_type = GLOB.species_list[species_id] + var/datum/species/species = new species_type() + + // Check the species decription. + // If it's not overridden, a stack trace will be thrown (and fail the test). + // If it's null, it was improperly overriden. Fail the test. + var/species_desc = species.get_species_description() + if(isnull(species_desc)) + Fail("Species [species] ([species_type]) is selectable, but did not properly implement get_species_description().") + + // Check the species lore. + // If it's not overridden, a stack trace will be thrown (and fail the test). + // If it's null, or returned a list, it was improperly overriden. Fail the test. + var/species_lore = species.get_species_lore() + if(isnull(species_lore)) + Fail("Species [species] ([species_type]) is selectable, but did not properly implement get_species_lore().") + else if(!islist(species_lore)) + Fail("Species [species] ([species_type]) is selectable, but did not properly implement get_species_lore() (Did not return a list).") + + qdel(species) diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/SpeciesPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/SpeciesPage.tsx index b3b6cbe1e65..c864c369324 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/SpeciesPage.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/SpeciesPage.tsx @@ -2,12 +2,9 @@ import { classes } from "common/react"; import { useBackend } from "../../backend"; import { BlockQuote, Box, Button, Divider, Icon, Section, Stack, Tooltip } from "../../components"; import { CharacterPreview } from "./CharacterPreview"; -import { createSetPreference, Food, PreferencesMenuData, ServerData, ServerSpeciesData } from "./data"; -import { Feature, Species, fallbackSpecies } from "./preferences/species/base"; +import { createSetPreference, Food, Perk, PreferencesMenuData, ServerData, Species } from "./data"; import { ServerPreferencesFetcher } from "./ServerPreferencesFetcher"; -const requireSpecies = require.context("./preferences/species"); - const FOOD_ICONS = { [Food.Cloth]: "tshirt", [Food.Dairy]: "cheese", @@ -17,7 +14,7 @@ const FOOD_ICONS = { [Food.Gross]: "trash", [Food.Junkfood]: "pizza-slice", [Food.Meat]: "hamburger", - [Food.Nuts]: "acorn", + [Food.Nuts]: "seedling", [Food.Raw]: "drumstick-bite", [Food.Seafood]: "fish", [Food.Sugar]: "candy-cane", @@ -100,15 +97,20 @@ const FoodList = (props: { }; const Diet = (props: { - likedFood: Food[], - dislikedFood: Food[], - toxicFood: Food[], + diet: Species["diet"], }) => { + + if (!props.diet) { + return null; + } + + const { liked_food, disliked_food, toxic_food } = props.diet; + return ( { - const { className, feature } = props; + const { className, perk } = props; return ( - {feature.name} + {perk.name} - {feature.description} + {perk.description} }> { - const { good, neutral, bad } = props.features; + + const { positive, negative, neutral } = props.perks; return ( - {good.map(feature => { + {positive.map(perk => { return ( - - + + perk={perk} /> ); })} @@ -189,24 +192,24 @@ const SpeciesFeatures = (props: { - {neutral.map(feature => { + {neutral.map(perk => { return ( - - + + perk={perk} /> ); })} - {bad.map(feature => { + {negative.map(perk => { return ( - - + + perk={perk} /> ); })} @@ -219,20 +222,16 @@ const SpeciesPageInner = (props: { handleClose: () => void, species: ServerData["species"], }, context) => { + const { act, data } = useBackend(context); const setSpecies = createSetPreference(act, "species"); - let species: [string, Species & ServerSpeciesData][] + let species: [string, Species][] = Object.entries(props.species) - .map(([species, serverData]) => { + .map(([species, data]) => { return [ species, - { - ...serverData, - ...(requireSpecies.keys().indexOf(`./${species}`) === -1 - ? fallbackSpecies - : requireSpecies(`./${species}`).default) as Species, - }, + data, ]; }); @@ -246,14 +245,14 @@ const SpeciesPageInner = (props: { return speciesKey === data.character_preferences.misc.species; })[0][1]; - const { lore } = currentSpecies; - return ( - +