mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
[MIRROR] Separate init_possible_values() from icon generation [MDB IGNORE] (#23221)
* Separate init_possible_values() from icon generation * Update clothing.dm * Update lizard.dm * Modular * Runtime fix * Modular adjustments * Fixes icon offset for undershirt * Update mutant_parts.dm * Update mutant_parts.dm * Fix a merge skew * Update mutant_parts.dm * More of a catch-all solution * Update _preference.dm --------- Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com>
This commit is contained in:
@@ -135,14 +135,18 @@ Choiced preferences can generate icons. This is how the clothing/species prefere
|
|||||||
savefile_key = "favorite_drink"
|
savefile_key = "favorite_drink"
|
||||||
should_generate_icons = TRUE // NEW! This is necessary.
|
should_generate_icons = TRUE // NEW! This is necessary.
|
||||||
|
|
||||||
// Instead of returning a flat list, this now returns an assoc list
|
|
||||||
// of values to icons.
|
|
||||||
/datum/preference/choiced/favorite_drink/init_possible_values()
|
/datum/preference/choiced/favorite_drink/init_possible_values()
|
||||||
return list(
|
return list("Milk", "Cola", "Water")
|
||||||
"Milk" = icon('drinks.dmi', "milk"),
|
|
||||||
"Cola" = icon('drinks.dmi', "cola"),
|
// New! This proc will get called for every value.
|
||||||
"Water" = icon('drinks.dmi', "water"),
|
/datum/preference/choiced/favorite_drink/icon_for(value)
|
||||||
)
|
switch (value)
|
||||||
|
if ("Milk")
|
||||||
|
return icon('drinks.dmi', "milk")
|
||||||
|
if ("Cola")
|
||||||
|
return icon('drinks.dmi', "cola")
|
||||||
|
if ("Water")
|
||||||
|
return icon('drinks.dmi', "water")
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, change your `.tsx` file to look like:
|
Then, change your `.tsx` file to look like:
|
||||||
|
|||||||
@@ -347,9 +347,8 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
|
|||||||
/// A preference that is a choice of one option among a fixed set.
|
/// A preference that is a choice of one option among a fixed set.
|
||||||
/// Used for preferences such as clothing.
|
/// Used for preferences such as clothing.
|
||||||
/datum/preference/choiced
|
/datum/preference/choiced
|
||||||
/// If this is TRUE, icons will be generated.
|
/// If this is TRUE, an icon will be generated for every value.
|
||||||
/// This is necessary for if your `init_possible_values()` override
|
/// If you implement this, you must implement `icon_for(value)` for every possible value.
|
||||||
/// returns an assoc list of names to atoms/icons.
|
|
||||||
var/should_generate_icons = FALSE
|
var/should_generate_icons = FALSE
|
||||||
|
|
||||||
var/list/cached_values
|
var/list/cached_values
|
||||||
@@ -376,34 +375,31 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
|
|||||||
return cached_values
|
return cached_values
|
||||||
|
|
||||||
/// Returns a list of every possible value, serialized.
|
/// Returns a list of every possible value, serialized.
|
||||||
/// Return value can be in the form of:
|
|
||||||
/// - A flat list of serialized values, such as list(MALE, FEMALE, PLURAL).
|
|
||||||
/// - An assoc list of serialized values to atoms/icons.
|
|
||||||
/datum/preference/choiced/proc/get_choices_serialized()
|
/datum/preference/choiced/proc/get_choices_serialized()
|
||||||
// Override `init_values()` instead.
|
// Override `init_values()` instead.
|
||||||
SHOULD_NOT_OVERRIDE(TRUE)
|
SHOULD_NOT_OVERRIDE(TRUE)
|
||||||
|
|
||||||
var/list/serialized_choices = list()
|
var/list/serialized_choices = list()
|
||||||
var/choices = get_choices()
|
|
||||||
|
|
||||||
if (should_generate_icons)
|
for (var/choice in get_choices())
|
||||||
for (var/choice in choices)
|
|
||||||
serialized_choices[serialize(choice)] = choices[choice]
|
|
||||||
else
|
|
||||||
for (var/choice in choices)
|
|
||||||
serialized_choices += serialize(choice)
|
serialized_choices += serialize(choice)
|
||||||
|
|
||||||
return serialized_choices
|
return serialized_choices
|
||||||
|
|
||||||
/// Returns a list of every possible value.
|
/// Returns a list of every possible value.
|
||||||
/// This must be overriden by `/datum/preference/choiced` subtypes.
|
/// This must be overriden by `/datum/preference/choiced` subtypes.
|
||||||
/// Return value can be in the form of:
|
/// If `should_generate_icons` is TRUE, then you will also need to implement `icon_for(value)`
|
||||||
/// - A flat list of raw values, such as list(MALE, FEMALE, PLURAL).
|
/// for every possible value.
|
||||||
/// - An assoc list of raw values to atoms/icons, in which case
|
|
||||||
/// icons will be generated.
|
|
||||||
/datum/preference/choiced/proc/init_possible_values()
|
/datum/preference/choiced/proc/init_possible_values()
|
||||||
CRASH("`init_possible_values()` was not implemented for [type]!")
|
CRASH("`init_possible_values()` was not implemented for [type]!")
|
||||||
|
|
||||||
|
/// When `should_generate_icons` is TRUE, this proc is called for every value.
|
||||||
|
/// It can return either an icon or a typepath to an atom to create.
|
||||||
|
/datum/preference/choiced/proc/icon_for(value)
|
||||||
|
SHOULD_CALL_PARENT(FALSE)
|
||||||
|
SHOULD_NOT_SLEEP(TRUE)
|
||||||
|
CRASH("`icon_for()` was not implemented for [type], even though should_generate_icons = TRUE!")
|
||||||
|
|
||||||
/datum/preference/choiced/is_valid(value)
|
/datum/preference/choiced/is_valid(value)
|
||||||
return value in get_choices()
|
return value in get_choices()
|
||||||
|
|
||||||
@@ -453,51 +449,6 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key())
|
|||||||
/datum/preference/color/is_valid(value)
|
/datum/preference/color/is_valid(value)
|
||||||
return findtext(value, GLOB.is_color)
|
return findtext(value, GLOB.is_color)
|
||||||
|
|
||||||
/// Takes an assoc list of names to /datum/sprite_accessory and returns a value
|
|
||||||
/// fit for `/datum/preference/init_possible_values()`
|
|
||||||
/proc/possible_values_for_sprite_accessory_list(list/datum/sprite_accessory/sprite_accessories)
|
|
||||||
var/list/possible_values = list()
|
|
||||||
for (var/name in sprite_accessories)
|
|
||||||
var/datum/sprite_accessory/sprite_accessory = sprite_accessories[name]
|
|
||||||
if (istype(sprite_accessory))
|
|
||||||
possible_values[name] = icon(sprite_accessory.icon, sprite_accessory.icon_state)
|
|
||||||
else
|
|
||||||
// This means it didn't have an icon state
|
|
||||||
possible_values[name] = icon('icons/mob/landmarks.dmi', "x")
|
|
||||||
return possible_values
|
|
||||||
|
|
||||||
/// Takes an assoc list of names to /datum/sprite_accessory and returns a value
|
|
||||||
/// fit for `/datum/preference/init_possible_values()`
|
|
||||||
/// Different from `possible_values_for_sprite_accessory_list` in that it takes a list of layers
|
|
||||||
/// such as BEHIND, FRONT, and ADJ.
|
|
||||||
/// It also takes a "body part name", such as body_markings, moth_wings, etc
|
|
||||||
/// They are expected to be in order from lowest to top.
|
|
||||||
/proc/possible_values_for_sprite_accessory_list_for_body_part(
|
|
||||||
list/datum/sprite_accessory/sprite_accessories,
|
|
||||||
body_part,
|
|
||||||
list/layers,
|
|
||||||
)
|
|
||||||
var/list/possible_values = list()
|
|
||||||
|
|
||||||
for (var/name in sprite_accessories)
|
|
||||||
var/datum/sprite_accessory/sprite_accessory = sprite_accessories[name]
|
|
||||||
if(sprite_accessory.locked)
|
|
||||||
continue
|
|
||||||
|
|
||||||
var/icon/final_icon
|
|
||||||
|
|
||||||
for (var/layer in layers)
|
|
||||||
var/icon/icon = icon(sprite_accessory.icon, "m_[body_part]_[sprite_accessory.icon_state]_[layer]")
|
|
||||||
|
|
||||||
if (isnull(final_icon))
|
|
||||||
final_icon = icon
|
|
||||||
else
|
|
||||||
final_icon.Blend(icon, ICON_OVERLAY)
|
|
||||||
|
|
||||||
possible_values[name] = final_icon
|
|
||||||
|
|
||||||
return possible_values
|
|
||||||
|
|
||||||
/// A numeric preference with a minimum and maximum value
|
/// A numeric preference with a minimum and maximum value
|
||||||
/datum/preference/numeric
|
/datum/preference/numeric
|
||||||
/// The minimum value
|
/// The minimum value
|
||||||
|
|||||||
@@ -6,14 +6,13 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/ai_core_display/init_possible_values()
|
/datum/preference/choiced/ai_core_display/init_possible_values()
|
||||||
var/list/values = list()
|
return GLOB.ai_core_display_screens - "Portrait"
|
||||||
|
|
||||||
values["Random"] = icon('icons/mob/silicon/ai.dmi', "questionmark")
|
/datum/preference/choiced/ai_core_display/icon_for(value)
|
||||||
|
if (value == "Random")
|
||||||
for (var/screen in GLOB.ai_core_display_screens - "Portrait" - "Random")
|
return icon('icons/mob/silicon/ai.dmi', "questionmark")
|
||||||
values[screen] = icon('icons/mob/silicon/ai.dmi', resolve_ai_icon_sync(screen))
|
else
|
||||||
|
return icon('icons/mob/silicon/ai.dmi', resolve_ai_icon_sync(value))
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/ai_core_display/is_accessible(datum/preferences/preferences)
|
/datum/preference/choiced/ai_core_display/is_accessible(datum/preferences/preferences)
|
||||||
if (!..(preferences))
|
if (!..(preferences))
|
||||||
|
|||||||
@@ -6,15 +6,13 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/ai_emote_display/init_possible_values()
|
/datum/preference/choiced/ai_emote_display/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys(GLOB.ai_status_display_emotes)
|
||||||
|
|
||||||
values["Random"] = icon('icons/mob/silicon/ai.dmi', "questionmark")
|
/datum/preference/choiced/ai_emote_display/icon_for(value)
|
||||||
|
if (value == "Random")
|
||||||
for(var/emote in GLOB.ai_status_display_emotes)
|
return icon('icons/mob/silicon/ai.dmi', "questionmark")
|
||||||
var/emote_icon = GLOB.ai_status_display_emotes[emote]
|
else
|
||||||
values[emote] = icon('icons/obj/machines/status_display.dmi', emote_icon)
|
return icon('icons/obj/machines/status_display.dmi', GLOB.ai_status_display_emotes[value])
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/ai_emote_display/is_accessible(datum/preferences/preferences)
|
/datum/preference/choiced/ai_emote_display/is_accessible(datum/preferences/preferences)
|
||||||
if (!..(preferences))
|
if (!..(preferences))
|
||||||
|
|||||||
@@ -6,14 +6,13 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/ai_hologram_display/init_possible_values()
|
/datum/preference/choiced/ai_hologram_display/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys(GLOB.ai_hologram_icons) + "Random"
|
||||||
|
|
||||||
values["Random"] = icon('icons/mob/silicon/ai.dmi', "questionmark")
|
/datum/preference/choiced/ai_hologram_display/icon_for(value)
|
||||||
|
if (value == "Random")
|
||||||
for(var/hologram in GLOB.ai_hologram_icons - "Random")
|
return icon('icons/mob/silicon/ai.dmi', "questionmark")
|
||||||
values[hologram] = icon(GLOB.ai_hologram_icons[hologram], GLOB.ai_hologram_icon_state[hologram])
|
else
|
||||||
|
return icon(GLOB.ai_hologram_icons[value], GLOB.ai_hologram_icon_state[value])
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/ai_hologram_display/is_accessible(datum/preferences/preferences)
|
/datum/preference/choiced/ai_hologram_display/is_accessible(datum/preferences/preferences)
|
||||||
if (!..(preferences))
|
if (!..(preferences))
|
||||||
|
|||||||
@@ -15,9 +15,8 @@
|
|||||||
if (!preference.should_generate_icons)
|
if (!preference.should_generate_icons)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
var/list/choices = preference.get_choices_serialized()
|
for (var/preference_value in preference.get_choices())
|
||||||
for (var/preference_value in choices)
|
var/create_icon_of = preference.icon_for(preference_value)
|
||||||
var/create_icon_of = choices[preference_value]
|
|
||||||
|
|
||||||
var/icon/icon
|
var/icon/icon
|
||||||
var/icon_state
|
var/icon_state
|
||||||
@@ -31,7 +30,7 @@
|
|||||||
else
|
else
|
||||||
CRASH("[create_icon_of] is an invalid preference value (from [preference_key]:[preference_value]).")
|
CRASH("[create_icon_of] is an invalid preference value (from [preference_key]:[preference_value]).")
|
||||||
|
|
||||||
to_insert[preference.get_spritesheet_key(preference_value)] = list(icon, icon_state)
|
to_insert[preference.get_spritesheet_key(preference.serialize(preference_value))] = list(icon, icon_state)
|
||||||
|
|
||||||
for (var/spritesheet_key in to_insert)
|
for (var/spritesheet_key in to_insert)
|
||||||
var/list/inserting = to_insert[spritesheet_key]
|
var/list/inserting = to_insert[spritesheet_key]
|
||||||
|
|||||||
@@ -1,28 +1,16 @@
|
|||||||
/proc/generate_values_for_underwear(list/accessory_list, list/icons, color, icon_offset) //SKYRAT EDIT CHANGE - Colorable Undershirt/Socks
|
/proc/generate_underwear_icon(datum/sprite_accessory/accessory, icon/base_icon, color, icon_offset = 0) //SKYRAT EDIT CHANGE : adds icon_offset - Colorable Undershirt/Socks
|
||||||
var/icon/lower_half = icon('icons/blanks/32x32.dmi', "nothing")
|
var/icon/final_icon = new(base_icon)
|
||||||
|
|
||||||
for (var/icon in icons)
|
if (!isnull(accessory))
|
||||||
lower_half.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', icon), ICON_OVERLAY)
|
var/icon/accessory_icon = icon(accessory.icon, accessory.icon_state) // SKYRAT EDIT CHANGE: ORIGINAL - var/icon/accessory_icon = icon('icons/mob/clothing/underwear.dmi', accessory.icon_state)
|
||||||
|
|
||||||
var/list/values = list()
|
|
||||||
|
|
||||||
for (var/accessory_name in accessory_list)
|
|
||||||
var/icon/icon_with_socks = new(lower_half)
|
|
||||||
var/datum/sprite_accessory/accessory = accessory_list[accessory_name]
|
|
||||||
//SKYRAT EDIT CHANGE
|
|
||||||
if (accessory_name != "Nude" && accessory)
|
|
||||||
var/icon/accessory_icon = icon(accessory.icon, accessory.icon_state)
|
|
||||||
//SKYRAT EDIT CHANGE END
|
|
||||||
if (color && !accessory.use_static)
|
if (color && !accessory.use_static)
|
||||||
accessory_icon.Blend(color, ICON_MULTIPLY)
|
accessory_icon.Blend(color, ICON_MULTIPLY)
|
||||||
icon_with_socks.Blend(accessory_icon, ICON_OVERLAY)
|
final_icon.Blend(accessory_icon, ICON_OVERLAY)
|
||||||
icon_with_socks.Crop(10, 1+icon_offset, 22, 13+icon_offset) //SKYRAT EDIT CHANGE - Colorable Undershirt/Socks
|
|
||||||
|
|
||||||
icon_with_socks.Scale(32, 32)
|
final_icon.Crop(10, 1+icon_offset, 22, 13+icon_offset) //SKYRAT EDIT CHANGE : adds icon_offset - Colorable Undershirt/Socks
|
||||||
|
final_icon.Scale(32, 32)
|
||||||
|
|
||||||
values[accessory_name] = icon_with_socks
|
return final_icon
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/// Backpack preference
|
/// Backpack preference
|
||||||
/datum/preference/choiced/backpack
|
/datum/preference/choiced/backpack
|
||||||
@@ -33,22 +21,37 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/backpack/init_possible_values()
|
/datum/preference/choiced/backpack/init_possible_values()
|
||||||
var/list/values = list()
|
return list(
|
||||||
|
GBACKPACK,
|
||||||
|
GSATCHEL,
|
||||||
|
LSATCHEL,
|
||||||
|
GDUFFELBAG,
|
||||||
|
DBACKPACK,
|
||||||
|
DSATCHEL,
|
||||||
|
DDUFFELBAG,
|
||||||
|
)
|
||||||
|
|
||||||
values[GBACKPACK] = /obj/item/storage/backpack
|
/datum/preference/choiced/backpack/icon_for(value)
|
||||||
values[GSATCHEL] = /obj/item/storage/backpack/satchel
|
switch (value)
|
||||||
values[LSATCHEL] = /obj/item/storage/backpack/satchel/leather
|
if (GBACKPACK)
|
||||||
values[GDUFFELBAG] = /obj/item/storage/backpack/duffelbag
|
return /obj/item/storage/backpack
|
||||||
|
if (GSATCHEL)
|
||||||
|
return /obj/item/storage/backpack/satchel
|
||||||
|
if (LSATCHEL)
|
||||||
|
return /obj/item/storage/backpack/satchel/leather
|
||||||
|
if (GDUFFELBAG)
|
||||||
|
return /obj/item/storage/backpack/duffelbag
|
||||||
|
|
||||||
// In a perfect world, these would be your department's backpack.
|
// In a perfect world, these would be your department's backpack.
|
||||||
// However, this doesn't factor in assistants, or no high slot, and would
|
// However, this doesn't factor in assistants, or no high slot, and would
|
||||||
// also increase the spritesheet size a lot.
|
// also increase the spritesheet size a lot.
|
||||||
// I play medical doctor, and so medical doctor you get.
|
// I play medical doctor, and so medical doctor you get.
|
||||||
values[DBACKPACK] = /obj/item/storage/backpack/medic
|
if (DBACKPACK)
|
||||||
values[DSATCHEL] = /obj/item/storage/backpack/satchel/med
|
return /obj/item/storage/backpack/medic
|
||||||
values[DDUFFELBAG] = /obj/item/storage/backpack/duffelbag/med
|
if (DSATCHEL)
|
||||||
|
return /obj/item/storage/backpack/satchel/med
|
||||||
return values
|
if (DDUFFELBAG)
|
||||||
|
return /obj/item/storage/backpack/duffelbag/med
|
||||||
|
|
||||||
/datum/preference/choiced/backpack/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/backpack/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.backpack = value
|
target.backpack = value
|
||||||
@@ -62,12 +65,17 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/jumpsuit/init_possible_values()
|
/datum/preference/choiced/jumpsuit/init_possible_values()
|
||||||
var/list/values = list()
|
return list(
|
||||||
|
PREF_SUIT,
|
||||||
|
PREF_SKIRT,
|
||||||
|
)
|
||||||
|
|
||||||
values[PREF_SUIT] = /obj/item/clothing/under/color/grey
|
/datum/preference/choiced/jumpsuit/icon_for(value)
|
||||||
values[PREF_SKIRT] = /obj/item/clothing/under/color/jumpskirt/grey
|
switch (value)
|
||||||
|
if (PREF_SUIT)
|
||||||
return values
|
return /obj/item/clothing/under/color/grey
|
||||||
|
if (PREF_SKIRT)
|
||||||
|
return /obj/item/clothing/under/color/jumpskirt/grey
|
||||||
|
|
||||||
/datum/preference/choiced/jumpsuit/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/jumpsuit/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.jumpsuit_style = value
|
target.jumpsuit_style = value
|
||||||
@@ -81,7 +89,17 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/socks/init_possible_values()
|
/datum/preference/choiced/socks/init_possible_values()
|
||||||
return generate_values_for_underwear(GLOB.socks_list, list("human_r_leg", "human_l_leg"))
|
return assoc_to_keys_features(GLOB.socks_list)
|
||||||
|
|
||||||
|
/datum/preference/choiced/socks/icon_for(value)
|
||||||
|
var/static/icon/lower_half
|
||||||
|
|
||||||
|
if (isnull(lower_half))
|
||||||
|
lower_half = icon('icons/blanks/32x32.dmi', "nothing")
|
||||||
|
lower_half.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_r_leg"), ICON_OVERLAY)
|
||||||
|
lower_half.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_leg"), ICON_OVERLAY)
|
||||||
|
|
||||||
|
return generate_underwear_icon(GLOB.socks_list[value], lower_half)
|
||||||
|
|
||||||
/datum/preference/choiced/socks/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/socks/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.socks = value
|
target.socks = value
|
||||||
@@ -95,7 +113,12 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/undershirt/init_possible_values()
|
/datum/preference/choiced/undershirt/init_possible_values()
|
||||||
var/icon/body = icon('icons/mob/human/bodyparts_greyscale.dmi', "human_r_leg")
|
return assoc_to_keys_features(GLOB.undershirt_list)
|
||||||
|
|
||||||
|
/datum/preference/choiced/undershirt/icon_for(value)
|
||||||
|
var/static/icon/body
|
||||||
|
if (isnull(body))
|
||||||
|
body = icon('icons/mob/human/bodyparts_greyscale.dmi', "human_r_leg")
|
||||||
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_leg"), ICON_OVERLAY)
|
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_leg"), ICON_OVERLAY)
|
||||||
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_r_arm"), ICON_OVERLAY)
|
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_r_arm"), ICON_OVERLAY)
|
||||||
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_arm"), ICON_OVERLAY)
|
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_arm"), ICON_OVERLAY)
|
||||||
@@ -103,20 +126,15 @@
|
|||||||
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_hand"), ICON_OVERLAY)
|
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_hand"), ICON_OVERLAY)
|
||||||
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_chest_m"), ICON_OVERLAY)
|
body.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_chest_m"), ICON_OVERLAY)
|
||||||
|
|
||||||
var/list/values = list()
|
|
||||||
|
|
||||||
for (var/accessory_name in GLOB.undershirt_list)
|
|
||||||
var/icon/icon_with_undershirt = icon(body)
|
var/icon/icon_with_undershirt = icon(body)
|
||||||
|
|
||||||
if (accessory_name != "Nude")
|
if (value != "Nude")
|
||||||
var/datum/sprite_accessory/accessory = GLOB.undershirt_list[accessory_name]
|
var/datum/sprite_accessory/accessory = GLOB.undershirt_list[value]
|
||||||
icon_with_undershirt.Blend(icon('icons/mob/clothing/underwear.dmi', accessory.icon_state), ICON_OVERLAY)
|
icon_with_undershirt.Blend(icon(accessory.icon, accessory.icon_state), ICON_OVERLAY) // SKYRAT EDIT CHANGE: ORIGINAL - icon_with_undershirt.Blend(icon('icons/mob/clothing/underwear.dmi', accessory.icon_state), ICON_OVERLAY)
|
||||||
|
|
||||||
icon_with_undershirt.Crop(9, 9, 23, 23)
|
icon_with_undershirt.Crop(10, 11, 22, 23) // SKYRAT EDIT CHANGE : ORIGINAL - icon_with_undershirt.Crop(9, 9, 23, 23)
|
||||||
icon_with_undershirt.Scale(32, 32)
|
icon_with_undershirt.Scale(32, 32)
|
||||||
values[accessory_name] = icon_with_undershirt
|
return icon_with_undershirt
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/undershirt/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/undershirt/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.undershirt = value
|
target.undershirt = value
|
||||||
@@ -130,7 +148,18 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/underwear/init_possible_values()
|
/datum/preference/choiced/underwear/init_possible_values()
|
||||||
return generate_values_for_underwear(GLOB.underwear_list, list("human_chest_m", "human_r_leg", "human_l_leg"), COLOR_ALMOST_BLACK)
|
return assoc_to_keys_features(GLOB.underwear_list)
|
||||||
|
|
||||||
|
/datum/preference/choiced/underwear/icon_for(value)
|
||||||
|
var/static/icon/lower_half
|
||||||
|
|
||||||
|
if (isnull(lower_half))
|
||||||
|
lower_half = icon('icons/blanks/32x32.dmi', "nothing")
|
||||||
|
lower_half.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_chest_m"), ICON_OVERLAY)
|
||||||
|
lower_half.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_r_leg"), ICON_OVERLAY)
|
||||||
|
lower_half.Blend(icon('icons/mob/human/bodyparts_greyscale.dmi', "human_l_leg"), ICON_OVERLAY)
|
||||||
|
|
||||||
|
return generate_underwear_icon(GLOB.underwear_list[value], lower_half, COLOR_ALMOST_BLACK, icon_offset = 5) // SKYRAT EDIT CHANGE : ICON_OFFSET
|
||||||
|
|
||||||
/datum/preference/choiced/underwear/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/underwear/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.underwear = value
|
target.underwear = value
|
||||||
|
|||||||
@@ -71,12 +71,10 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
/datum/preference/choiced/ghost_form/init_possible_values()
|
/datum/preference/choiced/ghost_form/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys(ghost_forms)
|
||||||
|
|
||||||
for (var/ghost_form in ghost_forms)
|
/datum/preference/choiced/ghost_form/icon_for(value)
|
||||||
values[ghost_form] = icon('icons/mob/simple/mob.dmi', ghost_form)
|
return icon('icons/mob/simple/mob.dmi', value)
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/ghost_form/create_default_value()
|
/datum/preference/choiced/ghost_form/create_default_value()
|
||||||
return "ghost"
|
return "ghost"
|
||||||
|
|||||||
@@ -5,14 +5,13 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/glasses/init_possible_values()
|
/datum/preference/choiced/glasses/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys(GLOB.nearsighted_glasses) + "Random"
|
||||||
|
|
||||||
values["Random"] = icon('icons/effects/random_spawners.dmi', "questionmark")
|
/datum/preference/choiced/glasses/icon_for(value)
|
||||||
|
if (value == "Random")
|
||||||
for(var/glass_design in GLOB.nearsighted_glasses - "Random")
|
return icon('icons/effects/random_spawners.dmi', "questionmark")
|
||||||
values[glass_design] = icon('icons/obj/clothing/glasses.dmi', "glasses_[lowertext(glass_design)]")
|
else
|
||||||
|
return icon('icons/obj/clothing/glasses.dmi', "glasses_[lowertext(value)]")
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/glasses/is_accessible(datum/preferences/preferences)
|
/datum/preference/choiced/glasses/is_accessible(datum/preferences/preferences)
|
||||||
if (!..(preferences))
|
if (!..(preferences))
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
/proc/generate_possible_values_for_sprite_accessories_on_head(accessories)
|
/proc/generate_icon_with_head_accessory(datum/sprite_accessory/sprite_accessory)
|
||||||
var/list/values = possible_values_for_sprite_accessory_list(accessories)
|
var/static/icon/head_icon
|
||||||
|
if (isnull(head_icon))
|
||||||
var/icon/head_icon = icon('icons/mob/human/bodyparts_greyscale.dmi', "human_head_m")
|
head_icon = icon('icons/mob/human/bodyparts_greyscale.dmi', "human_head_m")
|
||||||
head_icon.Blend(skintone2hex("caucasian1"), ICON_MULTIPLY)
|
head_icon.Blend(skintone2hex("caucasian1"), ICON_MULTIPLY)
|
||||||
|
|
||||||
for (var/name in values)
|
if (isnull(sprite_accessory))
|
||||||
var/datum/sprite_accessory/accessory = accessories[name]
|
return head_icon
|
||||||
if (accessory == null || accessory.icon_state == null)
|
|
||||||
continue
|
ASSERT(istype(sprite_accessory))
|
||||||
|
|
||||||
var/icon/final_icon = new(head_icon)
|
var/icon/final_icon = new(head_icon)
|
||||||
|
|
||||||
var/icon/beard_icon = values[name]
|
var/icon/head_accessory_icon = icon(sprite_accessory.icon, sprite_accessory.icon_state)
|
||||||
beard_icon.Blend(COLOR_DARK_BROWN, ICON_MULTIPLY)
|
head_accessory_icon.Blend(COLOR_DARK_BROWN, ICON_MULTIPLY)
|
||||||
final_icon.Blend(beard_icon, ICON_OVERLAY)
|
final_icon.Blend(head_accessory_icon, ICON_OVERLAY)
|
||||||
|
|
||||||
final_icon.Crop(10, 19, 22, 31)
|
final_icon.Crop(10, 19, 22, 31)
|
||||||
final_icon.Scale(32, 32)
|
final_icon.Scale(32, 32)
|
||||||
|
|
||||||
values[name] = final_icon
|
return final_icon
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/color/eye_color
|
/datum/preference/color/eye_color
|
||||||
priority = PREFERENCE_PRIORITY_BODYPARTS
|
priority = PREFERENCE_PRIORITY_BODYPARTS
|
||||||
@@ -64,7 +62,10 @@
|
|||||||
relevant_head_flag = HEAD_FACIAL_HAIR
|
relevant_head_flag = HEAD_FACIAL_HAIR
|
||||||
|
|
||||||
/datum/preference/choiced/facial_hairstyle/init_possible_values()
|
/datum/preference/choiced/facial_hairstyle/init_possible_values()
|
||||||
return generate_possible_values_for_sprite_accessories_on_head(GLOB.facial_hairstyles_list)
|
return assoc_to_keys_features(GLOB.facial_hairstyles_list)
|
||||||
|
|
||||||
|
/datum/preference/choiced/facial_hairstyle/icon_for(value)
|
||||||
|
return generate_icon_with_head_accessory(GLOB.facial_hairstyles_list[value])
|
||||||
|
|
||||||
/datum/preference/choiced/facial_hairstyle/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/facial_hairstyle/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.set_facial_hairstyle(value, update = FALSE)
|
target.set_facial_hairstyle(value, update = FALSE)
|
||||||
@@ -137,7 +138,10 @@
|
|||||||
relevant_head_flag = HEAD_HAIR
|
relevant_head_flag = HEAD_HAIR
|
||||||
|
|
||||||
/datum/preference/choiced/hairstyle/init_possible_values()
|
/datum/preference/choiced/hairstyle/init_possible_values()
|
||||||
return generate_possible_values_for_sprite_accessories_on_head(GLOB.hairstyles_list)
|
return assoc_to_keys_features(GLOB.hairstyles_list)
|
||||||
|
|
||||||
|
/datum/preference/choiced/hairstyle/icon_for(value)
|
||||||
|
return generate_icon_with_head_accessory(GLOB.hairstyles_list[value])
|
||||||
|
|
||||||
/datum/preference/choiced/hairstyle/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/hairstyle/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.set_hairstyle(value, update = FALSE)
|
target.set_hairstyle(value, update = FALSE)
|
||||||
|
|||||||
@@ -6,9 +6,12 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/ethereal_color/init_possible_values()
|
/datum/preference/choiced/ethereal_color/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys(GLOB.color_list_ethereal)
|
||||||
|
|
||||||
var/icon/ethereal_base = icon('icons/mob/human/species/ethereal/bodyparts.dmi', "ethereal_head")
|
/datum/preference/choiced/ethereal_color/icon_for(value)
|
||||||
|
var/static/icon/ethereal_base
|
||||||
|
if (isnull(ethereal_base))
|
||||||
|
ethereal_base = icon('icons/mob/human/species/ethereal/bodyparts.dmi', "ethereal_head")
|
||||||
ethereal_base.Blend(icon('icons/mob/human/species/ethereal/bodyparts.dmi', "ethereal_chest"), ICON_OVERLAY)
|
ethereal_base.Blend(icon('icons/mob/human/species/ethereal/bodyparts.dmi', "ethereal_chest"), ICON_OVERLAY)
|
||||||
ethereal_base.Blend(icon('icons/mob/human/species/ethereal/bodyparts.dmi', "ethereal_l_arm"), ICON_OVERLAY)
|
ethereal_base.Blend(icon('icons/mob/human/species/ethereal/bodyparts.dmi', "ethereal_l_arm"), ICON_OVERLAY)
|
||||||
ethereal_base.Blend(icon('icons/mob/human/species/ethereal/bodyparts.dmi', "ethereal_r_arm"), ICON_OVERLAY)
|
ethereal_base.Blend(icon('icons/mob/human/species/ethereal/bodyparts.dmi', "ethereal_r_arm"), ICON_OVERLAY)
|
||||||
@@ -20,14 +23,9 @@
|
|||||||
ethereal_base.Scale(64, 64)
|
ethereal_base.Scale(64, 64)
|
||||||
ethereal_base.Crop(15, 64, 15 + 31, 64 - 31)
|
ethereal_base.Crop(15, 64, 15 + 31, 64 - 31)
|
||||||
|
|
||||||
for (var/name in GLOB.color_list_ethereal)
|
|
||||||
var/color = GLOB.color_list_ethereal[name]
|
|
||||||
|
|
||||||
var/icon/icon = new(ethereal_base)
|
var/icon/icon = new(ethereal_base)
|
||||||
icon.Blend(color, ICON_MULTIPLY)
|
icon.Blend(GLOB.color_list_ethereal[value], ICON_MULTIPLY)
|
||||||
values[name] = icon
|
return icon
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/ethereal_color/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/ethereal_color/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.dna.features["ethcolor"] = GLOB.color_list_ethereal[value]
|
target.dna.features["ethcolor"] = GLOB.color_list_ethereal[value]
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
/* SKYRAT EDIT REMOVAL
|
/* SKYRAT EDIT REMOVAL
|
||||||
/proc/generate_lizard_side_shots(list/sprite_accessories, key, include_snout = TRUE)
|
/proc/generate_lizard_side_shot(datum/sprite_accessory/sprite_accessory, key, include_snout = TRUE)
|
||||||
var/list/values = list()
|
var/static/icon/lizard
|
||||||
|
var/static/icon/lizard_with_snout
|
||||||
|
|
||||||
var/icon/lizard = icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_head", EAST)
|
if (isnull(lizard))
|
||||||
|
lizard = icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_head", EAST)
|
||||||
var/icon/eyes = icon('icons/mob/human/human_face.dmi', "eyes", EAST)
|
var/icon/eyes = icon('icons/mob/human/human_face.dmi', "eyes", EAST)
|
||||||
eyes.Blend(COLOR_GRAY, ICON_MULTIPLY)
|
eyes.Blend(COLOR_GRAY, ICON_MULTIPLY)
|
||||||
lizard.Blend(eyes, ICON_OVERLAY)
|
lizard.Blend(eyes, ICON_OVERLAY)
|
||||||
|
|
||||||
if (include_snout)
|
lizard_with_snout = icon(lizard)
|
||||||
lizard.Blend(icon('icons/mob/human/species/lizard/lizard_misc.dmi', "m_snout_round_ADJ", EAST), ICON_OVERLAY)
|
lizard_with_snout.Blend(icon('icons/mob/human/species/lizard/lizard_misc.dmi', "m_snout_round_ADJ", EAST), ICON_OVERLAY)
|
||||||
|
|
||||||
for (var/name in sprite_accessories)
|
var/icon/final_icon = include_snout ? icon(lizard_with_snout) : icon(lizard)
|
||||||
var/datum/sprite_accessory/sprite_accessory = sprite_accessories[name]
|
|
||||||
|
|
||||||
var/icon/final_icon = icon(lizard)
|
if (!isnull(sprite_accessory))
|
||||||
|
|
||||||
if (sprite_accessory.icon_state != "none")
|
|
||||||
var/icon/accessory_icon = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", EAST)
|
var/icon/accessory_icon = icon(sprite_accessory.icon, "m_[key]_[sprite_accessory.icon_state]_ADJ", EAST)
|
||||||
final_icon.Blend(accessory_icon, ICON_OVERLAY)
|
final_icon.Blend(accessory_icon, ICON_OVERLAY)
|
||||||
|
|
||||||
@@ -23,9 +22,7 @@
|
|||||||
final_icon.Scale(32, 32)
|
final_icon.Scale(32, 32)
|
||||||
final_icon.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY)
|
final_icon.Blend(COLOR_VIBRANT_LIME, ICON_MULTIPLY)
|
||||||
|
|
||||||
values[name] = final_icon
|
return final_icon
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_body_markings
|
/datum/preference/choiced/lizard_body_markings
|
||||||
savefile_key = "feature_lizard_body_markings"
|
savefile_key = "feature_lizard_body_markings"
|
||||||
@@ -36,14 +33,12 @@
|
|||||||
relevant_mutant_bodypart = "body_markings"
|
relevant_mutant_bodypart = "body_markings"
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_body_markings/init_possible_values()
|
/datum/preference/choiced/lizard_body_markings/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys_features(GLOB.body_markings_list)
|
||||||
|
|
||||||
var/icon/lizard = icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_chest_m")
|
/datum/preference/choiced/lizard_body_markings/icon_for(value)
|
||||||
|
var/datum/sprite_accessory/sprite_accessory = GLOB.body_markings_list[value]
|
||||||
|
|
||||||
for (var/name in GLOB.body_markings_list)
|
var/icon/final_icon = icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_chest_m")
|
||||||
var/datum/sprite_accessory/sprite_accessory = GLOB.body_markings_list[name]
|
|
||||||
|
|
||||||
var/icon/final_icon = icon(lizard)
|
|
||||||
|
|
||||||
if (sprite_accessory.icon_state != "none")
|
if (sprite_accessory.icon_state != "none")
|
||||||
var/icon/body_markings_icon = icon(
|
var/icon/body_markings_icon = icon(
|
||||||
@@ -58,9 +53,7 @@
|
|||||||
final_icon.Scale(26, 32)
|
final_icon.Scale(26, 32)
|
||||||
final_icon.Crop(-2, 1, 29, 32)
|
final_icon.Crop(-2, 1, 29, 32)
|
||||||
|
|
||||||
values[name] = final_icon
|
return final_icon
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_body_markings/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/lizard_body_markings/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.dna.features["body_markings"] = value
|
target.dna.features["body_markings"] = value
|
||||||
@@ -73,7 +66,10 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_frills/init_possible_values()
|
/datum/preference/choiced/lizard_frills/init_possible_values()
|
||||||
return generate_lizard_side_shots(GLOB.frills_list, "frills")
|
return assoc_to_keys_features(GLOB.frills_list)
|
||||||
|
|
||||||
|
/datum/preference/choiced/lizard_frills/icon_for(value)
|
||||||
|
return generate_lizard_side_shot(GLOB.frills_list[value], "frills")
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_frills/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/lizard_frills/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.dna.features["frills"] = value
|
target.dna.features["frills"] = value
|
||||||
@@ -86,7 +82,10 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_horns/init_possible_values()
|
/datum/preference/choiced/lizard_horns/init_possible_values()
|
||||||
return generate_lizard_side_shots(GLOB.horns_list, "horns")
|
return assoc_to_keys_features(GLOB.horns_list)
|
||||||
|
|
||||||
|
/datum/preference/choiced/lizard_horns/icon_for(value)
|
||||||
|
return generate_lizard_side_shot(GLOB.horns_list[value], "horns")
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_horns/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/lizard_horns/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.dna.features["horns"] = value
|
target.dna.features["horns"] = value
|
||||||
@@ -111,7 +110,10 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_snout/init_possible_values()
|
/datum/preference/choiced/lizard_snout/init_possible_values()
|
||||||
return generate_lizard_side_shots(GLOB.snouts_list, "snout", include_snout = FALSE)
|
return assoc_to_keys_features(GLOB.snouts_list)
|
||||||
|
|
||||||
|
/datum/preference/choiced/lizard_snout/icon_for(value)
|
||||||
|
return generate_lizard_side_shot(GLOB.snouts_list[value], "snout", include_snout = FALSE)
|
||||||
|
|
||||||
/datum/preference/choiced/lizard_snout/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/lizard_snout/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.dna.features["snout"] = value
|
target.dna.features["snout"] = value
|
||||||
|
|||||||
@@ -7,24 +7,24 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/moth_antennae/init_possible_values()
|
/datum/preference/choiced/moth_antennae/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys_features(GLOB.moth_antennae_list)
|
||||||
|
|
||||||
var/icon/moth_head = icon('icons/mob/human/species/moth/bodyparts.dmi', "moth_head")
|
/datum/preference/choiced/moth_antennae/icon_for(value)
|
||||||
moth_head.Blend(icon('icons/mob/human/human_face.dmi', "motheyes"), ICON_OVERLAY)
|
var/static/icon/moth_head
|
||||||
|
|
||||||
for (var/antennae_name in GLOB.moth_antennae_list)
|
if (isnull(moth_head))
|
||||||
var/datum/sprite_accessory/antennae = GLOB.moth_antennae_list[antennae_name]
|
moth_head = icon('icons/mob/human/species/moth/bodyparts.dmi', "moth_head")
|
||||||
if(antennae.locked)
|
moth_head.Blend(icon('icons/mob/human/human_face.dmi', "motheyes_l"), ICON_OVERLAY)
|
||||||
continue
|
moth_head.Blend(icon('icons/mob/human/human_face.dmi', "motheyes_r"), ICON_OVERLAY)
|
||||||
|
|
||||||
|
var/datum/sprite_accessory/antennae = GLOB.moth_antennae_list[value]
|
||||||
|
|
||||||
var/icon/icon_with_antennae = new(moth_head)
|
var/icon/icon_with_antennae = new(moth_head)
|
||||||
icon_with_antennae.Blend(icon(antennae.icon, "m_moth_antennae_[antennae.icon_state]_FRONT"), ICON_OVERLAY)
|
icon_with_antennae.Blend(icon(antennae.icon, "m_moth_antennae_[antennae.icon_state]_FRONT"), ICON_OVERLAY)
|
||||||
icon_with_antennae.Scale(64, 64)
|
icon_with_antennae.Scale(64, 64)
|
||||||
icon_with_antennae.Crop(15, 64, 15 + 31, 64 - 31)
|
icon_with_antennae.Crop(15, 64, 15 + 31, 64 - 31)
|
||||||
|
|
||||||
values[antennae.name] = icon_with_antennae
|
return icon_with_antennae
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/moth_antennae/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/moth_antennae/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.dna.features["moth_antennae"] = value
|
target.dna.features["moth_antennae"] = value
|
||||||
@@ -38,34 +38,34 @@
|
|||||||
relevant_mutant_bodypart = "moth_markings"
|
relevant_mutant_bodypart = "moth_markings"
|
||||||
|
|
||||||
/datum/preference/choiced/moth_markings/init_possible_values()
|
/datum/preference/choiced/moth_markings/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys_features(GLOB.moth_markings_list)
|
||||||
|
|
||||||
var/icon/moth_body = icon('icons/blanks/32x32.dmi', "nothing")
|
/datum/preference/choiced/moth_markings/icon_for(value)
|
||||||
|
var/static/list/body_parts = list(
|
||||||
moth_body.Blend(icon('icons/mob/human/species/moth/moth_wings.dmi', "m_moth_wings_plain_BEHIND"), ICON_OVERLAY)
|
|
||||||
|
|
||||||
var/list/body_parts = list(
|
|
||||||
/obj/item/bodypart/head/moth,
|
/obj/item/bodypart/head/moth,
|
||||||
/obj/item/bodypart/chest/moth,
|
/obj/item/bodypart/chest/moth,
|
||||||
/obj/item/bodypart/arm/left/moth,
|
/obj/item/bodypart/arm/left/moth,
|
||||||
/obj/item/bodypart/arm/right/moth,
|
/obj/item/bodypart/arm/right/moth,
|
||||||
)
|
)
|
||||||
|
|
||||||
for (var/obj/item/bodypart/body_part in body_parts)
|
var/static/icon/moth_body
|
||||||
var/gender = (initial(body_part.is_dimorphic)) ? "_m" : ""
|
if (isnull(moth_body))
|
||||||
moth_body.Blend(icon('icons/mob/human/species/moth/bodyparts.dmi', "moth_[body_part][gender]"), ICON_OVERLAY)
|
moth_body = icon('icons/blanks/32x32.dmi', "nothing")
|
||||||
|
|
||||||
moth_body.Blend(icon('icons/mob/human/human_face.dmi', "motheyes"), ICON_OVERLAY)
|
moth_body.Blend(icon('icons/mob/human/species/moth/moth_wings.dmi', "m_moth_wings_plain_BEHIND"), ICON_OVERLAY)
|
||||||
|
|
||||||
for (var/markings_name in GLOB.moth_markings_list)
|
for (var/obj/item/bodypart/body_part as anything in body_parts)
|
||||||
var/datum/sprite_accessory/markings = GLOB.moth_markings_list[markings_name]
|
moth_body.Blend(icon('icons/mob/human/species/moth/bodyparts.dmi', initial(body_part.icon_state)), ICON_OVERLAY)
|
||||||
if(markings.locked)
|
|
||||||
continue
|
moth_body.Blend(icon('icons/mob/human/human_face.dmi', "motheyes_l"), ICON_OVERLAY)
|
||||||
|
moth_body.Blend(icon('icons/mob/human/human_face.dmi', "motheyes_r"), ICON_OVERLAY)
|
||||||
|
|
||||||
|
var/datum/sprite_accessory/markings = GLOB.moth_markings_list[value]
|
||||||
var/icon/icon_with_markings = new(moth_body)
|
var/icon/icon_with_markings = new(moth_body)
|
||||||
|
|
||||||
if (markings_name != "None")
|
if (value != "None")
|
||||||
for (var/body_part in body_parts)
|
for (var/obj/item/bodypart/body_part as anything in body_parts)
|
||||||
var/icon/body_part_icon = icon(markings.icon, "[markings.icon_state]_[body_part]")
|
var/icon/body_part_icon = icon(markings.icon, "[markings.icon_state]_[initial(body_part.body_zone)]")
|
||||||
body_part_icon.Crop(1, 1, 32, 32)
|
body_part_icon.Crop(1, 1, 32, 32)
|
||||||
icon_with_markings.Blend(body_part_icon, ICON_OVERLAY)
|
icon_with_markings.Blend(body_part_icon, ICON_OVERLAY)
|
||||||
|
|
||||||
@@ -76,9 +76,7 @@
|
|||||||
icon_with_markings.Scale(64, 64)
|
icon_with_markings.Scale(64, 64)
|
||||||
icon_with_markings.Crop(15, 64, 15 + 31, 64 - 31)
|
icon_with_markings.Crop(15, 64, 15 + 31, 64 - 31)
|
||||||
|
|
||||||
values[markings.name] = icon_with_markings
|
return icon_with_markings
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/moth_markings/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/moth_markings/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.dna.features["moth_markings"] = value
|
target.dna.features["moth_markings"] = value
|
||||||
@@ -91,11 +89,13 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/moth_wings/init_possible_values()
|
/datum/preference/choiced/moth_wings/init_possible_values()
|
||||||
return possible_values_for_sprite_accessory_list_for_body_part(
|
return assoc_to_keys_features(GLOB.moth_wings_list)
|
||||||
GLOB.moth_wings_list,
|
|
||||||
"moth_wings",
|
/datum/preference/choiced/moth_wings/icon_for(value)
|
||||||
list("BEHIND", "FRONT"),
|
var/datum/sprite_accessory/moth_wings = GLOB.moth_wings_list[value]
|
||||||
)
|
var/icon/final_icon = icon(moth_wings.icon, "m_moth_wings_[moth_wings.icon_state]_BEHIND")
|
||||||
|
final_icon.Blend(icon(moth_wings.icon, "m_moth_wings_[moth_wings.icon_state]_FRONT"), ICON_OVERLAY)
|
||||||
|
return final_icon
|
||||||
|
|
||||||
/datum/preference/choiced/moth_wings/apply_to_human(mob/living/carbon/human/target, value)
|
/datum/preference/choiced/moth_wings/apply_to_human(mob/living/carbon/human/target, value)
|
||||||
target.dna.features["moth_wings"] = value
|
target.dna.features["moth_wings"] = value
|
||||||
|
|||||||
@@ -8,16 +8,13 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/pod_hair/init_possible_values()
|
/datum/preference/choiced/pod_hair/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys_features(GLOB.pod_hair_list)
|
||||||
|
|
||||||
var/icon/pod_head = icon('icons/mob/human/bodyparts_greyscale.dmi', "pod_head_m")
|
/datum/preference/choiced/pod_hair/icon_for(value)
|
||||||
|
var/datum/sprite_accessory/pod_hair = GLOB.pod_hair_list[value]
|
||||||
|
|
||||||
for (var/pod_name in GLOB.pod_hair_list)
|
var/icon/icon_with_hair = icon('icons/mob/human/bodyparts_greyscale.dmi', "pod_head_m")
|
||||||
var/datum/sprite_accessory/pod_hair = GLOB.pod_hair_list[pod_name]
|
|
||||||
if(pod_hair.locked)
|
|
||||||
continue
|
|
||||||
|
|
||||||
var/icon/icon_with_hair = new(pod_head)
|
|
||||||
var/icon/icon_adj = icon(pod_hair.icon, "m_pod_hair_[pod_hair.icon_state]_ADJ")
|
var/icon/icon_adj = icon(pod_hair.icon, "m_pod_hair_[pod_hair.icon_state]_ADJ")
|
||||||
var/icon/icon_front = icon(pod_hair.icon, "m_pod_hair_[pod_hair.icon_state]_FRONT")
|
var/icon/icon_front = icon(pod_hair.icon, "m_pod_hair_[pod_hair.icon_state]_FRONT")
|
||||||
icon_adj.Blend(icon_front, ICON_OVERLAY)
|
icon_adj.Blend(icon_front, ICON_OVERLAY)
|
||||||
@@ -26,9 +23,7 @@
|
|||||||
icon_with_hair.Crop(15, 64, 15 + 31, 64 - 31)
|
icon_with_hair.Crop(15, 64, 15 + 31, 64 - 31)
|
||||||
icon_with_hair.Blend(COLOR_GREEN, ICON_MULTIPLY)
|
icon_with_hair.Blend(COLOR_GREEN, ICON_MULTIPLY)
|
||||||
|
|
||||||
values[pod_hair.name] = icon_with_hair
|
return icon_with_hair
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/pod_hair/create_default_value()
|
/datum/preference/choiced/pod_hair/create_default_value()
|
||||||
return pick(assoc_to_keys_features(GLOB.pod_hair_list))
|
return pick(assoc_to_keys_features(GLOB.pod_hair_list))
|
||||||
|
|||||||
@@ -11,12 +11,14 @@
|
|||||||
return "Inoculated" //eh, have em try out the mechanic first
|
return "Inoculated" //eh, have em try out the mechanic first
|
||||||
|
|
||||||
/datum/preference/choiced/vampire_status/init_possible_values()
|
/datum/preference/choiced/vampire_status/init_possible_values()
|
||||||
var/list/values = list()
|
return list("Inoculated", "Outcast")
|
||||||
|
|
||||||
values["Inoculated"] = icon('icons/obj/drinks/drinks.dmi', "bloodglass")
|
/datum/preference/choiced/vampire_status/icon_for(value)
|
||||||
values["Outcast"] = icon('icons/obj/medical/bloodpack.dmi', "generic_bloodpack")
|
switch (value)
|
||||||
|
if ("Inoculated")
|
||||||
return values
|
return icon('icons/obj/drinks/drinks.dmi', "bloodglass")
|
||||||
|
if ("Outcast")
|
||||||
|
return icon('icons/obj/medical/bloodpack.dmi', "generic_bloodpack")
|
||||||
|
|
||||||
///list that stores a vampire house name for each department
|
///list that stores a vampire house name for each department
|
||||||
GLOBAL_LIST_EMPTY(vampire_houses)
|
GLOBAL_LIST_EMPTY(vampire_houses)
|
||||||
|
|||||||
@@ -6,18 +6,16 @@
|
|||||||
should_generate_icons = TRUE
|
should_generate_icons = TRUE
|
||||||
|
|
||||||
/datum/preference/choiced/ui_style/init_possible_values()
|
/datum/preference/choiced/ui_style/init_possible_values()
|
||||||
var/list/values = list()
|
return assoc_to_keys(GLOB.available_ui_styles)
|
||||||
|
|
||||||
for (var/style in GLOB.available_ui_styles)
|
/datum/preference/choiced/ui_style/icon_for(value)
|
||||||
var/icon/icons = GLOB.available_ui_styles[style]
|
var/icon/icons = GLOB.available_ui_styles[value]
|
||||||
|
|
||||||
var/icon/icon = icon(icons, "hand_r")
|
var/icon/icon = icon(icons, "hand_r")
|
||||||
icon.Crop(1, 1, world.icon_size * 2, world.icon_size)
|
icon.Crop(1, 1, world.icon_size * 2, world.icon_size)
|
||||||
icon.Blend(icon(icons, "hand_l"), ICON_OVERLAY, world.icon_size)
|
icon.Blend(icon(icons, "hand_l"), ICON_OVERLAY, world.icon_size)
|
||||||
|
|
||||||
values[style] = icon
|
return icon
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
||||||
/datum/preference/choiced/ui_style/create_default_value()
|
/datum/preference/choiced/ui_style/create_default_value()
|
||||||
return GLOB.available_ui_styles[1]
|
return GLOB.available_ui_styles[1]
|
||||||
|
|||||||
@@ -258,7 +258,7 @@
|
|||||||
/obj/item/modular_computer/pda/shaftminer
|
/obj/item/modular_computer/pda/shaftminer
|
||||||
name = "shaft miner PDA"
|
name = "shaft miner PDA"
|
||||||
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
|
greyscale_config = /datum/greyscale_config/tablet/stripe_thick
|
||||||
greyscale_colors = "#927444#D6B328#6C3BA1"
|
greyscale_colors = "#927444#8b4c31#4c202d"
|
||||||
starting_programs = list(
|
starting_programs = list(
|
||||||
/datum/computer_file/program/skill_tracker,
|
/datum/computer_file/program/skill_tracker,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -49,3 +49,29 @@
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
TEST_ASSERT(!isnull(preference.main_feature_name), "Preference [preference_type] does not have a main_feature_name set!")
|
TEST_ASSERT(!isnull(preference.main_feature_name), "Preference [preference_type] does not have a main_feature_name set!")
|
||||||
|
|
||||||
|
/// Validates that every choiced preference with should_generate_icons implements icon_for,
|
||||||
|
/// and that every one that doesn't, doesn't.
|
||||||
|
/datum/unit_test/preferences_should_generate_icons_sanity
|
||||||
|
|
||||||
|
/datum/unit_test/preferences_should_generate_icons_sanity/Run()
|
||||||
|
for (var/preference_type in GLOB.preference_entries)
|
||||||
|
var/datum/preference/choiced/choiced_preference = GLOB.preference_entries[preference_type]
|
||||||
|
if (!istype(choiced_preference) || choiced_preference.abstract_type == preference_type)
|
||||||
|
continue
|
||||||
|
|
||||||
|
var/list/values = choiced_preference.get_choices()
|
||||||
|
|
||||||
|
if (choiced_preference.should_generate_icons)
|
||||||
|
for (var/value in values)
|
||||||
|
var/icon = choiced_preference.icon_for(value)
|
||||||
|
TEST_ASSERT(istype(icon, /icon) || ispath(icon), "[preference_type] gave [icon] as an icon for [value], which is not a valid value")
|
||||||
|
else
|
||||||
|
var/errored = FALSE
|
||||||
|
|
||||||
|
try
|
||||||
|
choiced_preference.icon_for(values[1])
|
||||||
|
catch
|
||||||
|
errored = TRUE
|
||||||
|
|
||||||
|
TEST_ASSERT(errored, "[preference_type] implemented icon_for, but does not have should_generate_icons = TRUE")
|
||||||
|
|||||||
@@ -108,7 +108,7 @@
|
|||||||
savefile_identifier = PREFERENCE_CHARACTER
|
savefile_identifier = PREFERENCE_CHARACTER
|
||||||
|
|
||||||
/// Path to the default sprite accessory
|
/// Path to the default sprite accessory
|
||||||
var/datum/sprite_accessory/default_accessory_type
|
var/datum/sprite_accessory/default_accessory_type = /datum/sprite_accessory/blank
|
||||||
/// Path to the corresponding /datum/preference/toggle to check if part is enabled.
|
/// Path to the corresponding /datum/preference/toggle to check if part is enabled.
|
||||||
var/datum/preference/toggle/type_to_check
|
var/datum/preference/toggle/type_to_check
|
||||||
/// Generates icons from the provided mutant bodypart for use in icon-enabled selection boxes in the prefs window.
|
/// Generates icons from the provided mutant bodypart for use in icon-enabled selection boxes in the prefs window.
|
||||||
@@ -124,6 +124,15 @@
|
|||||||
var/part_enabled = is_part_enabled(preferences)
|
var/part_enabled = is_part_enabled(preferences)
|
||||||
return (passed_initial_check || overriding) && part_enabled
|
return (passed_initial_check || overriding) && part_enabled
|
||||||
|
|
||||||
|
// icons are cached
|
||||||
|
/datum/preference/choiced/mutant_choice/icon_for(value)
|
||||||
|
if(!should_generate_icons)
|
||||||
|
// because of the way the unit tests are set up, we need this to crash here
|
||||||
|
CRASH("`icon_for()` was not implemented for [type], even though should_generate_icons = TRUE!")
|
||||||
|
|
||||||
|
var/list/cached_icons = get_choices()
|
||||||
|
return cached_icons[value]
|
||||||
|
|
||||||
/// Allows for dynamic assigning of icon states.
|
/// Allows for dynamic assigning of icon states.
|
||||||
/datum/preference/choiced/mutant_choice/proc/generate_icon_state(datum/sprite_accessory/sprite_accessory, original_icon_state)
|
/datum/preference/choiced/mutant_choice/proc/generate_icon_state(datum/sprite_accessory/sprite_accessory, original_icon_state)
|
||||||
return original_icon_state
|
return original_icon_state
|
||||||
@@ -160,7 +169,7 @@
|
|||||||
return list_of_accessories
|
return list_of_accessories
|
||||||
|
|
||||||
/datum/preference/choiced/mutant_choice/create_default_value()
|
/datum/preference/choiced/mutant_choice/create_default_value()
|
||||||
return initial(default_accessory_type?.name) || "None"
|
return initial(default_accessory_type.name)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this part enabled by the player?
|
* Is this part enabled by the player?
|
||||||
@@ -204,6 +213,9 @@
|
|||||||
if(!bodypart_is_visible)
|
if(!bodypart_is_visible)
|
||||||
value = create_default_value()
|
value = create_default_value()
|
||||||
|
|
||||||
|
if(value == "None")
|
||||||
|
return bodypart_is_visible
|
||||||
|
|
||||||
if(!target.dna.mutant_bodyparts[relevant_mutant_bodypart])
|
if(!target.dna.mutant_bodyparts[relevant_mutant_bodypart])
|
||||||
target.dna.mutant_bodyparts[relevant_mutant_bodypart] = list(MUTANT_INDEX_NAME = value, MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF"), MUTANT_INDEX_EMISSIVE_LIST = list(FALSE, FALSE, FALSE))
|
target.dna.mutant_bodyparts[relevant_mutant_bodypart] = list(MUTANT_INDEX_NAME = value, MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF"), MUTANT_INDEX_EMISSIVE_LIST = list(FALSE, FALSE, FALSE))
|
||||||
return bodypart_is_visible
|
return bodypart_is_visible
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
/datum/preference/choiced/socks/init_possible_values()
|
|
||||||
return generate_values_for_underwear(GLOB.socks_list, list("human_r_leg", "human_l_leg"), COLOR_ALMOST_BLACK, 0)
|
|
||||||
|
|
||||||
/datum/preference/choiced/socks/compile_constant_data()
|
/datum/preference/choiced/socks/compile_constant_data()
|
||||||
var/list/data = ..()
|
var/list/data = ..()
|
||||||
|
|
||||||
@@ -16,9 +13,6 @@
|
|||||||
var/datum/species/species = new species_type
|
var/datum/species/species = new species_type
|
||||||
return !(TRAIT_NO_UNDERWEAR in species.inherent_traits)
|
return !(TRAIT_NO_UNDERWEAR in species.inherent_traits)
|
||||||
|
|
||||||
/datum/preference/choiced/undershirt/init_possible_values()
|
|
||||||
return generate_values_for_underwear(GLOB.undershirt_list, list("human_chest_m", "human_r_arm", "human_l_arm", "human_r_leg", "human_l_leg", "human_r_hand", "human_l_hand"), COLOR_ALMOST_BLACK, 10)
|
|
||||||
|
|
||||||
/datum/preference/choiced/undershirt/compile_constant_data()
|
/datum/preference/choiced/undershirt/compile_constant_data()
|
||||||
var/list/data = ..()
|
var/list/data = ..()
|
||||||
|
|
||||||
@@ -34,9 +28,6 @@
|
|||||||
var/datum/species/species = new species_type
|
var/datum/species/species = new species_type
|
||||||
return !(TRAIT_NO_UNDERWEAR in species.inherent_traits)
|
return !(TRAIT_NO_UNDERWEAR in species.inherent_traits)
|
||||||
|
|
||||||
/datum/preference/choiced/underwear/init_possible_values()
|
|
||||||
return generate_values_for_underwear(GLOB.underwear_list, list("human_chest_m", "human_r_leg", "human_l_leg"), COLOR_ALMOST_BLACK, 5)
|
|
||||||
|
|
||||||
/datum/preference/choiced/underwear/is_accessible(datum/preferences/preferences)
|
/datum/preference/choiced/underwear/is_accessible(datum/preferences/preferences)
|
||||||
if (!..(preferences))
|
if (!..(preferences))
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
return (savefile_key in species.get_features())
|
return (savefile_key in species.get_features())
|
||||||
|
|
||||||
/datum/preference/choiced/genital/create_default_value()
|
/datum/preference/choiced/genital/create_default_value()
|
||||||
return initial(default_accessory_type?.name) || "None"
|
return initial(default_accessory_type.name)
|
||||||
|
|
||||||
/datum/preference/choiced/genital/init_possible_values()
|
/datum/preference/choiced/genital/init_possible_values()
|
||||||
return assoc_to_keys_features(GLOB.sprite_accessories[relevant_mutant_bodypart])
|
return assoc_to_keys_features(GLOB.sprite_accessories[relevant_mutant_bodypart])
|
||||||
|
|||||||
@@ -81,7 +81,6 @@
|
|||||||
/datum/preference/toggle/mutant_toggle/body_markings/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
/datum/preference/toggle/mutant_toggle/body_markings/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
|
|
||||||
/datum/preference/choiced/mutant_choice/body_markings
|
/datum/preference/choiced/mutant_choice/body_markings
|
||||||
savefile_key = "feature_body_markings"
|
savefile_key = "feature_body_markings"
|
||||||
relevant_mutant_bodypart = "body_markings"
|
relevant_mutant_bodypart = "body_markings"
|
||||||
@@ -95,7 +94,6 @@
|
|||||||
/datum/preference/choiced/mutant_choice/body_markings/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
/datum/preference/choiced/mutant_choice/body_markings/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
|
|
||||||
/datum/preference/tri_color/body_markings
|
/datum/preference/tri_color/body_markings
|
||||||
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
|
||||||
savefile_identifier = PREFERENCE_CHARACTER
|
savefile_identifier = PREFERENCE_CHARACTER
|
||||||
@@ -124,7 +122,6 @@
|
|||||||
/datum/preference/tri_bool/body_markings/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
/datum/preference/tri_bool/body_markings/apply_to_human(mob/living/carbon/human/target, value, datum/preferences/preferences)
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
|
|
||||||
/// Tails
|
/// Tails
|
||||||
|
|
||||||
/datum/preference/toggle/mutant_toggle/tail
|
/datum/preference/toggle/mutant_toggle/tail
|
||||||
|
|||||||
Reference in New Issue
Block a user