Merge branch 'master' of https://github.com/tgstation/tgstation into upstream-2025-11-05

This commit is contained in:
Roxy
2025-11-05 19:43:07 -05:00
461 changed files with 41708 additions and 37517 deletions
+5 -2
View File
@@ -4,8 +4,11 @@
GLOBAL_LIST_INIT(blacklisted_builds, list(
"1622" = "Bug breaking rendering can lead to wallhacks.",
))
))
GLOBAL_LIST_INIT(unrecommended_builds, list(
"1670" = "Bug breaking in-world text rendering.",
"1671" = "Bug breaking in-world text rendering.",
))
#define LIMITER_SIZE 5
#define CURRENT_SECOND 1
#define SECOND_COUNT 2
+40 -8
View File
@@ -50,17 +50,13 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
/proc/init_preference_entries()
var/list/output = list()
for (var/datum/preference/preference_type as anything in subtypesof(/datum/preference))
if (initial(preference_type.abstract_type) == preference_type)
continue
for (var/datum/preference/preference_type as anything in valid_subtypesof(/datum/preference))
output[preference_type] = new preference_type
return output
/proc/init_preference_entries_by_key()
var/list/output = list()
for (var/datum/preference/preference_type as anything in subtypesof(/datum/preference))
if (initial(preference_type.abstract_type) == preference_type)
continue
for (var/datum/preference/preference_type as anything in valid_subtypesof(/datum/preference))
output[initial(preference_type.savefile_key)] = GLOB.preference_entries[preference_type]
return output
@@ -113,7 +109,7 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
/// If the selected species has this in its /datum/species/body_markings,
/// will show the feature as selectable.
var/relevant_body_markings = null
var/datum/bodypart_overlay/simple/body_marking/relevant_body_markings = null
/// If the selected species has this in its /datum/species/inherent_traits,
/// will show the feature as selectable.
@@ -121,7 +117,7 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
/// If the selected species has this in its /datum/species/var/external_organs,
/// will show the feature as selectable.
var/relevant_organ = null
var/obj/item/organ/relevant_organ = null
/// If the selected species has this head_flag by default,
/// will show the feature as selectable.
@@ -447,6 +443,42 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
return data
/// This subtype handles a lot of boilerplate for implementing a species preference tied to a feature key / sprite accessory
/datum/preference/choiced/species_feature
abstract_type = /datum/preference/choiced/species_feature
/// What feature key does this feature represent?
/// Does not need to be set, it will infer it from either relevant_organ or relevant_body_markings.
/// However you can set it manually if you have a more complex feature.
var/feature_key
/datum/preference/choiced/species_feature/New()
. = ..()
if(relevant_organ && relevant_organ::bodypart_overlay)
feature_key ||= relevant_organ::bodypart_overlay::feature_key
main_feature_name ||= capitalize(relevant_organ::name)
if(relevant_body_markings)
feature_key ||= relevant_body_markings::dna_feature_key
main_feature_name ||= "Body markings"
if(isnull(feature_key))
CRASH("`feature_key` was not set or inferable for [type]!")
/datum/preference/choiced/species_feature/init_possible_values()
return assoc_to_keys_features(get_accessory_list())
/datum/preference/choiced/species_feature/create_default_value()
return get_consistent_feature_entry(get_accessory_list())
/datum/preference/choiced/species_feature/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[feature_key] = value
/// Returns what acessory list to draw from
/datum/preference/choiced/species_feature/proc/get_accessory_list() as /list
return SSaccessories.feature_list[feature_key]
/// Get a specific accessory for a given value
/datum/preference/choiced/species_feature/proc/get_accessory_for_value(value)
return get_accessory_list()[value]
/// A preference that represents an RGB color of something.
/// Will give the value as 6 hex digits, without a hash.
/datum/preference/color
@@ -6,13 +6,17 @@
should_generate_icons = TRUE
/datum/preference/choiced/ai_emote_display/init_possible_values()
return assoc_to_keys(GLOB.ai_status_display_emotes)
if(!length(GLOB.ai_status_display_all_options))
init_ai_status_display_options()
return assoc_to_keys(GLOB.ai_status_display_all_options)
/datum/preference/choiced/ai_emote_display/icon_for(value)
if (value == "Random")
return uni_icon('icons/mob/silicon/ai.dmi', "questionmark")
else
return uni_icon('icons/obj/machines/status_display.dmi', GLOB.ai_status_display_emotes[value])
if(!length(GLOB.ai_status_display_all_options))
init_ai_status_display_options()
return uni_icon('icons/obj/machines/status_display.dmi', GLOB.ai_status_display_all_options[value])
/datum/preference/choiced/ai_emote_display/is_accessible(datum/preferences/preferences)
if (!..(preferences))
@@ -0,0 +1,4 @@
/// Rename feature_human_tail and feature_human_ears to something not stupid
/datum/preferences/proc/migrate_felinid_feature_keys(list/save_data)
save_data["feature_cat_ears"] = save_data["feature_human_ears"]
save_data["feature_cat_tail"] = save_data["feature_human_tail"]
@@ -1,34 +1,15 @@
/* SKYRAT EDIT REMOVAL
/datum/preference/choiced/tail_felinid
savefile_key = "feature_human_tail" //savefile keys cannot be changed, blame whoever named them this way.
/datum/preference/choiced/species_feature/tail_felinid
savefile_key = "feature_cat_tail"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
can_randomize = FALSE
relevant_organ = /obj/item/organ/tail/cat
/datum/preference/choiced/tail_felinid/init_possible_values()
return assoc_to_keys_features(SSaccessories.tails_list_felinid)
/datum/preference/choiced/tail_felinid/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_TAIL_CAT] = value
/datum/preference/choiced/tail_felinid/create_default_value()
var/datum/sprite_accessory/tails/felinid/cat/tail = /datum/sprite_accessory/tails/felinid/cat
return initial(tail.name)
/datum/preference/choiced/felinid_ears
savefile_key = "feature_human_ears" //savefile keys cannot be changed, blame whoever named them this way.
/datum/preference/choiced/species_feature/felinid_ears
savefile_key = "feature_cat_ears"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
can_randomize = FALSE
relevant_organ = /obj/item/organ/ears/cat
/datum/preference/choiced/felinid_ears/init_possible_values()
return assoc_to_keys_features(SSaccessories.ears_list)
/datum/preference/choiced/felinid_ears/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_EARS] = value
/datum/preference/choiced/felinid_ears/create_default_value()
return /datum/sprite_accessory/ears/cat::name
*/
@@ -24,7 +24,7 @@
return final_icon
/datum/preference/choiced/lizard_body_markings
/datum/preference/choiced/species_feature/lizard_body_markings
savefile_key = "feature_lizard_body_markings"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_FEATURES
@@ -32,11 +32,8 @@
should_generate_icons = TRUE
relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/lizard
/datum/preference/choiced/lizard_body_markings/init_possible_values()
return assoc_to_keys_features(SSaccessories.lizard_markings_list)
/datum/preference/choiced/lizard_body_markings/icon_for(value)
var/datum/sprite_accessory/sprite_accessory = SSaccessories.lizard_markings_list[value]
/datum/preference/choiced/species_feature/lizard_body_markings/icon_for(value)
var/datum/sprite_accessory/sprite_accessory = get_accessory_for_value(value)
var/datum/universal_icon/final_icon = uni_icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_chest_m")
@@ -55,10 +52,7 @@
return final_icon
/datum/preference/choiced/lizard_body_markings/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_LIZARD_MARKINGS] = value
/datum/preference/choiced/lizard_frills
/datum/preference/choiced/species_feature/lizard_frills
savefile_key = "feature_lizard_frills"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_FEATURES
@@ -66,16 +60,10 @@
should_generate_icons = TRUE
relevant_organ = /obj/item/organ/frills
/datum/preference/choiced/lizard_frills/init_possible_values()
return assoc_to_keys_features(SSaccessories.frills_list)
/datum/preference/choiced/species_feature/lizard_frills/icon_for(value)
return generate_lizard_side_shot(get_accessory_for_value(value), "frills")
/datum/preference/choiced/lizard_frills/icon_for(value)
return generate_lizard_side_shot(SSaccessories.frills_list[value], "frills")
/datum/preference/choiced/lizard_frills/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_FRILLS] = value
/datum/preference/choiced/lizard_horns
/datum/preference/choiced/species_feature/lizard_horns
savefile_key = "feature_lizard_horns"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_FEATURES
@@ -83,14 +71,8 @@
should_generate_icons = TRUE
relevant_organ = /obj/item/organ/horns
/datum/preference/choiced/lizard_horns/init_possible_values()
return assoc_to_keys_features(SSaccessories.horns_list)
/datum/preference/choiced/lizard_horns/icon_for(value)
return generate_lizard_side_shot(SSaccessories.horns_list[value], "horns")
/datum/preference/choiced/lizard_horns/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_HORNS] = value
/datum/preference/choiced/species_feature/lizard_horns/icon_for(value)
return generate_lizard_side_shot(get_accessory_for_value(value), "horns")
/datum/preference/choiced/lizard_legs
savefile_key = "feature_lizard_legs"
@@ -131,7 +113,7 @@
var/datum/species/species_type = preferences.read_preference(/datum/preference/choiced/species)
return initial(species_type.digitigrade_customization) == DIGITIGRADE_OPTIONAL
/datum/preference/choiced/lizard_snout
/datum/preference/choiced/species_feature/lizard_snout
savefile_key = "feature_lizard_snout"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_FEATURES
@@ -139,40 +121,18 @@
should_generate_icons = TRUE
relevant_organ = /obj/item/organ/snout
/datum/preference/choiced/lizard_snout/init_possible_values()
return assoc_to_keys_features(SSaccessories.snouts_list)
/datum/preference/choiced/species_feature/lizard_snout/icon_for(value)
return generate_lizard_side_shot(get_accessory_for_value(value), "snout", include_snout = FALSE)
/datum/preference/choiced/lizard_snout/icon_for(value)
return generate_lizard_side_shot(SSaccessories.snouts_list[value], "snout", include_snout = FALSE)
/datum/preference/choiced/lizard_snout/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_SNOUT] = value
/datum/preference/choiced/lizard_spines
/datum/preference/choiced/species_feature/lizard_spines
savefile_key = "feature_lizard_spines"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
relevant_organ = /obj/item/organ/spines
/datum/preference/choiced/lizard_spines/init_possible_values()
return assoc_to_keys_features(SSaccessories.spines_list)
/datum/preference/choiced/lizard_spines/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_SPINES] = value
/datum/preference/choiced/lizard_tail
/datum/preference/choiced/species_feature/lizard_tail
savefile_key = "feature_lizard_tail"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
relevant_organ = /obj/item/organ/tail/lizard
/datum/preference/choiced/lizard_tail/init_possible_values()
return assoc_to_keys_features(SSaccessories.tails_list_lizard)
/datum/preference/choiced/lizard_tail/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_TAIL_LIZARD] = value
/datum/preference/choiced/lizard_tail/create_default_value()
return /datum/sprite_accessory/tails/lizard/smooth::name
*/
@@ -1,19 +1,8 @@
/* SKYRAT EDIT REMOVAL START
/datum/preference/choiced/monkey_tail
/datum/preference/choiced/species_feature/monkey_tail
savefile_key = "feature_monkey_tail"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
relevant_organ = /obj/item/organ/tail/monkey
can_randomize = FALSE
/datum/preference/choiced/monkey_tail/init_possible_values()
return assoc_to_keys_features(SSaccessories.tails_list_monkey)
/datum/preference/choiced/monkey_tail/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_TAIL_MONKEY] = value
/datum/preference/choiced/monkey_tail/create_default_value()
var/datum/sprite_accessory/tails/monkey/default/tail = /datum/sprite_accessory/tails/monkey/default
return initial(tail.name)
return /datum/sprite_accessory/tails/monkey/default::name
*/
@@ -1,5 +1,5 @@
/* SKYRAT EDIT REMOVAL
/datum/preference/choiced/moth_antennae
/datum/preference/choiced/species_feature/moth_antennae
savefile_key = "feature_moth_antennae"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_FEATURES
@@ -7,10 +7,7 @@
should_generate_icons = TRUE
relevant_organ = /obj/item/organ/antennae
/datum/preference/choiced/moth_antennae/init_possible_values()
return assoc_to_keys_features(SSaccessories.moth_antennae_list)
/datum/preference/choiced/moth_antennae/icon_for(value)
/datum/preference/choiced/species_feature/moth_antennae/icon_for(value)
var/static/datum/universal_icon/moth_head
if (isnull(moth_head))
@@ -18,7 +15,7 @@
moth_head.blend_icon(uni_icon('icons/mob/human/human_face.dmi', "motheyes_l"), ICON_OVERLAY)
moth_head.blend_icon(uni_icon('icons/mob/human/human_face.dmi', "motheyes_r"), ICON_OVERLAY)
var/datum/sprite_accessory/antennae = SSaccessories.moth_antennae_list[value]
var/datum/sprite_accessory/antennae = get_accessory_for_value(value)
var/datum/universal_icon/icon_with_antennae = moth_head.copy()
icon_with_antennae.blend_icon(uni_icon(antennae.icon, "m_moth_antennae_[antennae.icon_state]_FRONT"), ICON_OVERLAY)
@@ -27,10 +24,7 @@
return icon_with_antennae
/datum/preference/choiced/moth_antennae/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_MOTH_ANTENNAE] = value
/datum/preference/choiced/moth_markings
/datum/preference/choiced/species_feature/moth_markings
savefile_key = "feature_moth_markings"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_FEATURES
@@ -38,10 +32,7 @@
should_generate_icons = TRUE
relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/moth
/datum/preference/choiced/moth_markings/init_possible_values()
return assoc_to_keys_features(SSaccessories.moth_markings_list)
/datum/preference/choiced/moth_markings/icon_for(value)
/datum/preference/choiced/species_feature/moth_markings/icon_for(value)
var/static/list/body_parts = list(
/obj/item/bodypart/head/moth,
/obj/item/bodypart/chest/moth,
@@ -59,7 +50,7 @@
moth_body.blend_icon(uni_icon('icons/mob/human/human_face.dmi', "motheyes_l"), ICON_OVERLAY)
moth_body.blend_icon(uni_icon('icons/mob/human/human_face.dmi', "motheyes_r"), ICON_OVERLAY)
var/datum/sprite_accessory/markings = SSaccessories.moth_markings_list[value]
var/datum/sprite_accessory/markings = get_accessory_for_value(value)
var/datum/universal_icon/icon_with_markings = moth_body.copy()
if (value != SPRITE_ACCESSORY_NONE)
@@ -77,10 +68,7 @@
return icon_with_markings
/datum/preference/choiced/moth_markings/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_MOTH_MARKINGS] = value
/datum/preference/choiced/moth_wings
/datum/preference/choiced/species_feature/moth_wings
savefile_key = "feature_moth_wings"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_FEATURES
@@ -88,13 +76,7 @@
should_generate_icons = TRUE
relevant_organ = /obj/item/organ/wings/moth
/datum/preference/choiced/moth_wings/init_possible_values()
return assoc_to_keys_features(SSaccessories.moth_wings_list)
/datum/preference/choiced/moth_wings/icon_for(value)
var/datum/sprite_accessory/moth_wings = SSaccessories.moth_wings_list[value]
/datum/preference/choiced/species_feature/moth_wings/icon_for(value)
var/datum/sprite_accessory/moth_wings = get_accessory_for_value(value)
return uni_icon(moth_wings.icon, "m_moth_wings_[moth_wings.icon_state]_BEHIND")
/datum/preference/choiced/moth_wings/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_MOTH_WINGS] = value
*/
@@ -1,13 +1,7 @@
/* SKYRAT EDIT REMOVAL
/datum/preference/choiced/mushroom_cap
/datum/preference/choiced/species_feature/mushroom_cap
savefile_key = "feature_mushperson_cap"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
relevant_organ = /obj/item/organ/mushroom_cap
/datum/preference/choiced/mushroom_cap/init_possible_values()
return assoc_to_keys_features(SSaccessories.caps_list)
/datum/preference/choiced/mushroom_cap/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_MUSH_CAP] = value
*/
@@ -1,6 +1,6 @@
// SKYRAT EDIT: REPLACED BY /datum/preference/choiced/mutant_choice/pod_hair IN mutant_parts.dm
/*
/datum/preference/choiced/pod_hair
/datum/preference/choiced/species_feature/pod_hair
savefile_key = "feature_pod_hair"
savefile_identifier = PREFERENCE_CHARACTER
category = PREFERENCE_CATEGORY_FEATURES
@@ -8,11 +8,8 @@
should_generate_icons = TRUE
relevant_organ = /obj/item/organ/pod_hair
/datum/preference/choiced/pod_hair/init_possible_values()
return assoc_to_keys_features(SSaccessories.pod_hair_list)
/datum/preference/choiced/pod_hair/icon_for(value)
var/datum/sprite_accessory/pod_hair = SSaccessories.pod_hair_list[value]
/datum/preference/choiced/species_feature/pod_hair/icon_for(value)
var/datum/sprite_accessory/pod_hair = get_accessory_for_value(value)
var/datum/universal_icon/icon_with_hair = uni_icon('icons/mob/human/bodyparts_greyscale.dmi', "pod_head_m")
@@ -25,10 +22,4 @@
icon_with_hair.blend_color(COLOR_GREEN, ICON_MULTIPLY)
return icon_with_hair
/datum/preference/choiced/pod_hair/create_default_value()
return pick(assoc_to_keys_features(SSaccessories.pod_hair_list))
/datum/preference/choiced/pod_hair/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features[FEATURE_POD_HAIR] = value
*/
+3 -1
View File
@@ -13,7 +13,7 @@
/// You do not need to raise this if you are adding new values that have sane defaults.
/// Only raise this value when changing the meaning/format/name/layout of an existing value
/// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 50
#define SAVEFILE_VERSION_MAX 51
#define IS_DATA_OBSOLETE(version) (version == SAVE_DATA_OBSOLETE)
#define SHOULD_UPDATE_DATA(version) (version >= SAVE_DATA_NO_ERROR && version < SAVEFILE_VERSION_MAX)
@@ -163,6 +163,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
quirk_to_migrate = "Spiritual",
new_typepath = /datum/personality/spiritual,
)
if(current_version < 51)
migrate_felinid_feature_keys(save_data)
/// checks through keybindings for outdated unbound keys and updates them
/datum/preferences/proc/check_keybindings()