mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
Reduces species feature boilerplate (#93570)
## About The Pull Request Rather than having 100 separate list variables on `SSaccessories`, have 1 list for all feature keys that are associated with sprite accessories This way you can get a feature by doing `SSaccessories.feature_list[key]`, instead of necessitating `SSaccessories.ears_list`, `SSaccessories.tail_list`, etc. This lets us cut back on a lot of boilerplate in prefs, dna, and organs ## Why It's Good For The Game We can see the benefit in this example: This is all the code for horn DNA, bodypart overlay, and preference ```dm /datum/dna_block/feature/accessory/horn feature_key = FEATURE_HORNS ``` ```dm /datum/bodypart_overlay/mutant/horns layers = EXTERNAL_ADJACENT feature_key = FEATURE_HORNS dyable = TRUE /datum/bodypart_overlay/mutant/horns/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner) return !(bodypart_owner.owner?.obscured_slots & HIDEHAIR) ``` ```dm /datum/preference/choiced/species_feature/lizard_horns savefile_key = "feature_lizard_horns" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_FEATURES main_feature_name = "Horns" should_generate_icons = TRUE relevant_organ = /obj/item/organ/horns /datum/preference/choiced/species_feature/lizard_horns/icon_for(value) return generate_lizard_side_shot(get_accessory_for_value(value), "horns") ``` ## Changelog 🆑 Melbert refactor: Refactored species unique organs slightly, particularly how they are set up at game start. Report any oddities, like invisible tails or wings /🆑 --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -109,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.
|
||||
@@ -117,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.
|
||||
@@ -443,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
|
||||
|
||||
@@ -1,32 +1,13 @@
|
||||
/datum/preference/choiced/tail_felinid
|
||||
/datum/preference/choiced/species_feature/tail_felinid
|
||||
savefile_key = "feature_human_tail" //savefile keys cannot be changed, blame whoever named them this way.
|
||||
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
|
||||
/datum/preference/choiced/species_feature/felinid_ears
|
||||
savefile_key = "feature_human_ears" //savefile keys cannot be changed, blame whoever named them this way.
|
||||
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
|
||||
|
||||
@@ -23,7 +23,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
|
||||
@@ -31,11 +31,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")
|
||||
|
||||
@@ -54,10 +51,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
|
||||
@@ -65,16 +59,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
|
||||
@@ -82,14 +70,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"
|
||||
@@ -130,7 +112,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
|
||||
@@ -138,38 +120,17 @@
|
||||
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,15 +1,6 @@
|
||||
/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()
|
||||
return /datum/sprite_accessory/tails/monkey/default::name
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/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
|
||||
@@ -6,10 +6,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))
|
||||
@@ -17,7 +14,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)
|
||||
@@ -26,10 +23,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
|
||||
@@ -37,10 +31,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,
|
||||
@@ -58,7 +49,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)
|
||||
@@ -76,10 +67,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
|
||||
@@ -87,12 +75,6 @@
|
||||
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,11 +1,5 @@
|
||||
/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,4 +1,4 @@
|
||||
/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
|
||||
@@ -6,11 +6,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")
|
||||
|
||||
@@ -23,9 +20,3 @@
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user