diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 553ea81b803..4076cf18292 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -95,6 +95,55 @@ data["autohiss"] = pref.autohiss data["emote_sound_mode"] = pref.read_preference(/datum/preference/choiced/living/emote_sound_mode) + // Get species stats so they can be displayed + var/datum/species/species = null + var/mob/living/carbon/human/dummy/mannequin/mannequin = get_mannequin(pref.client_ckey) + if(mannequin) + species = mannequin.species + else if(pref.species) + species = GLOB.all_species[pref.species] + else + species = GLOB.all_species[SPECIES_HUMAN] + + var/list/species_stats = list( + "total_health" = species.total_health, + "slowdown" = species.slowdown, + "brute_mod" = species.brute_mod, + "burn_mod" = species.burn_mod, + "oxy_mod" = species.oxy_mod, + "toxins_mod" = species.toxins_mod, + "radiation_mod" = species.radiation_mod, + "flash_mod" = species.flash_mod, + "pain_mod" = species.pain_mod, + "stun_mod" = species.stun_mod, + "weaken_mod" = species.weaken_mod, + "lightweight" = species.lightweight, + "dispersed_eyes" = species.dispersed_eyes, + "trashcan" = species.trashcan, + "eat_minerals" = species.eat_minerals, + "darksight" = species.darksight, + "chem_strength_tox" = species.chem_strength_tox, + "cold_level_1" = species.cold_level_1, + "heat_level_1" = species.heat_level_1, + "chem_strength_heal" = species.chem_strength_heal, + "siemens_coefficient" = species.siemens_coefficient, + "has_vibration_sense" = species.has_vibration_sense, + "item_slowdown_mod" = species.item_slowdown_mod, + "body_temperature" = species.body_temperature, + "hazard_low_pressure" = species.hazard_low_pressure, + "breath_type" = GLOB.gas_data.name[species.breath_type], + "hazard_high_pressure" = species.hazard_high_pressure, + "soft_landing" = species.soft_landing, + "bloodsucker" = species.bloodsucker, + "can_space_freemove" = species.can_space_freemove, + "can_zero_g_move" = species.can_zero_g_move, + "water_breather" = species.water_breather, + "can_climb" = species.can_climb, + "has_flight" = (/mob/living/proc/flying_toggle in species.inherent_verbs), + ) + + data["species_stats"] = species_stats + return data /datum/category_item/player_setup_item/general/basic/tgui_static_data(mob/user) @@ -102,6 +151,45 @@ data["allow_metadata"] = CONFIG_GET(flag/allow_metadata) + var/list/human_stats = list( + "total_health" = /datum/species/human::total_health, + "slowdown" = /datum/species/human::slowdown, + "brute_mod" = /datum/species/human::brute_mod, + "burn_mod" = /datum/species/human::burn_mod, + "oxy_mod" = /datum/species/human::oxy_mod, + "toxins_mod" = /datum/species/human::toxins_mod, + "radiation_mod" = /datum/species/human::radiation_mod, + "flash_mod" = /datum/species/human::flash_mod, + "pain_mod" = /datum/species/human::pain_mod, + "stun_mod" = /datum/species/human::stun_mod, + "weaken_mod" = /datum/species/human::weaken_mod, + "lightweight" = FALSE, + "dispersed_eyes" = FALSE, + "trashcan" = FALSE, + "eat_minerals" = FALSE, + "darksight" = /datum/species/human::darksight, + "chem_strength_tox" = /datum/species/human::chem_strength_tox, + "cold_level_1" = /datum/species/human::cold_level_1, + "heat_level_1" = /datum/species/human::heat_level_1, + "chem_strength_heal" = /datum/species/human::chem_strength_heal, + "siemens_coefficient" = /datum/species/human::siemens_coefficient, + "has_vibration_sense" = FALSE, + "item_slowdown_mod" = /datum/species/human::item_slowdown_mod, + "body_temperature" = /datum/species/human::body_temperature, + "hazard_low_pressure" = /datum/species/human::hazard_low_pressure, + "breath_type" = GLOB.gas_data.name[/datum/species/human::breath_type], + "hazard_high_pressure" = /datum/species/human::hazard_high_pressure, + "soft_landing" = FALSE, + "bloodsucker" = FALSE, + "can_space_freemove" = FALSE, + "can_zero_g_move" = FALSE, + "water_breather" = FALSE, + "can_climb" = FALSE, + "has_flight" = FALSE, + ) + + data["basehuman_stats"] = human_stats + return data /datum/category_item/player_setup_item/general/basic/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/SubtabInfo.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/SubtabInfo.tsx index a88e939e601..219de37f74e 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/SubtabInfo.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/SubtabInfo.tsx @@ -4,7 +4,6 @@ import { Box, Button, ColorBox, - Divider, Floating, LabeledList, Stack, @@ -17,40 +16,8 @@ import { type GeneralDataConstant, type GeneralDataStatic, } from './data'; - -export const gender2icon = (gender: Gender) => { - switch (gender) { - case Gender.Female: { - return 'venus'; - } - case Gender.Male: { - return 'mars'; - } - case Gender.Plural: { - return 'transgender'; - } - case Gender.Neuter: { - return 'neuter'; - } - } -}; - -export const gender2pronouns = (gender: Gender) => { - switch (gender) { - case Gender.Female: { - return 'She/Her'; - } - case Gender.Male: { - return 'He/Him'; - } - case Gender.Plural: { - return 'They/Them'; - } - case Gender.Neuter: { - return 'It/Its'; - } - } -}; +import { gender2icon, gender2pronouns } from './functions'; +import { SpeciesBaseStats } from './stats/SpeciesSpaceStats'; export const GenderButton = (props: { gender: Gender; @@ -115,6 +82,7 @@ export const SubtabInfo = (props: { custom_species, selects_bodytype, custom_base, + species_stats, } = data; return ( @@ -251,9 +219,7 @@ export const SubtabInfo = (props: { ) : null} - - - + Language Keys {language_keys.map((key) => `${key} `)} @@ -264,9 +230,7 @@ export const SubtabInfo = (props: { {preferred_language} - - - + Runechat Color @@ -278,6 +242,13 @@ export const SubtabInfo = (props: { + + + + ); }; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/data.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/data.ts index 0ca65f12a62..9aee4502cd0 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/data.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/data.ts @@ -49,6 +49,7 @@ export type BasicData = { emote_sound_mode: string; persistence_settings: PersistanceEnum; + species_stats: SpeciesStats; }; export enum BodypartFlags { @@ -301,6 +302,7 @@ export type GeneralData = BasicData & export type GeneralDataStatic = { allow_metadata: BooleanLike; + basehuman_stats: SpeciesStats; can_play: Record; available_hair_styles: string[]; available_facial_styles: string[]; @@ -435,3 +437,40 @@ export type GeneralDataConstant = { wing_styles: Record; all_traits: Record; }; + +export type SpeciesStats = { + total_health: number; + slowdown: number; + brute_mod: number; + burn_mod: number; + oxy_mod: number; + toxins_mod: number; + radiation_mod: number; + flash_mod: number; + pain_mod: number; + stun_mod: number; + weaken_mod: number; + lightweight: BooleanLike; + has_vibration_sense: BooleanLike; + dispersed_eyes: BooleanLike; + trashcan: BooleanLike; + eat_minerals: BooleanLike; + darksight: number; + breath_type: string | null; + cold_level_1: number; + heat_level_1: number; + chem_strength_heal: number; + chem_strength_tox: number; + body_temperature: number; + item_slowdown_mod: number; + hazard_low_pressure: number; + hazard_high_pressure: number; + siemens_coefficient: number; + soft_landing: BooleanLike; + bloodsucker: BooleanLike; + can_zero_g_move: BooleanLike; + can_space_freemove: BooleanLike; + water_breather: BooleanLike; + has_flight: BooleanLike; + can_climb: BooleanLike; +}; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/functions.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/functions.ts new file mode 100644 index 00000000000..ce7f4bf1130 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/functions.ts @@ -0,0 +1,108 @@ +import { Gender } from './data'; + +export function gender2icon(gender: Gender): string { + switch (gender) { + case Gender.Female: { + return 'venus'; + } + case Gender.Male: { + return 'mars'; + } + case Gender.Plural: { + return 'transgender'; + } + case Gender.Neuter: { + return 'neuter'; + } + } +} + +export function gender2pronouns(gender: Gender): string { + switch (gender) { + case Gender.Female: { + return 'She/Her'; + } + case Gender.Male: { + return 'He/Him'; + } + case Gender.Plural: { + return 'They/Them'; + } + case Gender.Neuter: { + return 'It/Its'; + } + } +} + +export function breathetypeToColor( + type: string | null, + baseType: string | null, +): string | undefined { + if (!type) { + return 'green'; + } + if (type !== baseType) { + return 'red'; + } + return undefined; +} + +export function compareWithBase( + lower: number, + higher: number, + goodColor?: string, + badColor?: string, +): string | undefined { + if (lower < higher) { + return goodColor ?? 'green'; + } + if (lower > higher) { + return badColor ?? 'red'; + } + return undefined; +} + +export function formatStat(value: number, unit: string): string { + if (!Number.isFinite(value)) { + return 'N/A'; + } + return `${(Math.round(value * 100) / 100).toFixed(2)}${unit}`; +} + +export function slowdownToString(slowdown: number): string { + if (slowdown < -0.8) { + return 'Extremely Fast'; + } + if (slowdown < -0.2) { + return 'Very Fast'; + } + if (slowdown < -0.01) { + return 'Fast'; + } + if (slowdown < 0.2) { + return 'Average'; + } + if (slowdown < 0.4) { + return 'Slow'; + } + if (slowdown < 0.8) { + return 'Very Slow'; + } + return 'Extremely Slow'; +} + +export function darksightToString(sight: number): string { + if (sight <= 0) { + return 'None'; + } + if (sight < 2) { + return 'Low'; + } + if (sight < 5) { + return 'Basic'; + } + if (sight < 9) { + return 'Great'; + } + return 'Advanced'; +} diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/stats/SpeciesSpaceStats.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/stats/SpeciesSpaceStats.tsx new file mode 100644 index 00000000000..39d9ab228ff --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/bay_prefs/general/stats/SpeciesSpaceStats.tsx @@ -0,0 +1,269 @@ +import { Box, LabeledList, Stack } from 'tgui-core/components'; +import { YesNoBox } from '../../../../PublicLibraryWiki/WikiCommon/WikiQuickElements'; +import type { SpeciesStats } from '../data'; +import { + breathetypeToColor, + compareWithBase, + darksightToString, + formatStat, + slowdownToString, +} from '../functions'; +import { T0C } from 'tgui/constants'; + +export const SpeciesBaseStats = (props: { + speciesStats: SpeciesStats; + baseStats: SpeciesStats; +}) => { + const { speciesStats, baseStats } = props; + + return ( + + + Physiology + + + + {speciesStats.total_health} + + + + + {speciesStats.breath_type || "N/A"} + + + + + {formatStat(speciesStats.body_temperature - T0C, ' °C')} + + + + + {formatStat(speciesStats.cold_level_1 - T0C, ' °C')} + + + + + {formatStat(speciesStats.heat_level_1 - T0C, ' °C')} + + + + + {formatStat(Math.max(0, speciesStats.hazard_low_pressure), ' kPa')} + + + + + {formatStat(Math.max(0, speciesStats.hazard_high_pressure), ' kPa')} + + + + + + + Abilities + + + + {slowdownToString(speciesStats.slowdown)} + + + + + {darksightToString(speciesStats.darksight)} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modifiers + + + + {formatStat(speciesStats.brute_mod, 'x')} + + + + + {formatStat(speciesStats.burn_mod, 'x')} + + + + + {formatStat(speciesStats.toxins_mod, 'x')} + + + + + {formatStat(speciesStats.oxy_mod, 'x')} + + + + + {formatStat(speciesStats.radiation_mod, 'x')} + + + + + {formatStat(speciesStats.siemens_coefficient, 'x')} + + + + + {formatStat(speciesStats.flash_mod, 'x')} + + + + + {formatStat(speciesStats.pain_mod, 'x')} + + + + + {formatStat(speciesStats.stun_mod, 'x')} + + + + + {formatStat(speciesStats.chem_strength_heal, 'x')} + + + + + {formatStat(speciesStats.chem_strength_tox, 'x')} + + + + + {formatStat(speciesStats.item_slowdown_mod, 'x')} + + + + + + ); +};