diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index 87f7ba50f75..3e9b0bcc33c 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -163,7 +163,6 @@ DEFINE_BITFIELD(no_equip_flags, list( /// The sprite works fine for digitigrade legs as-is. #define CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON (1<<2) /// Auto-generates the leg portion of the sprite with GAGS -/// Suggested that you set [/obj/item/var/digitigrade_greyscale_config_worn] when using this flag #define CLOTHING_DIGITIGRADE_MASK (1<<3) /// All variation flags which render "correctly" on a digitigrade leg setup diff --git a/code/datums/greyscale/config_types/greyscale_configs/greyscale_clothes.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_clothes.dm index bdc2a7d2928..54ea9f41857 100644 --- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_clothes.dm +++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_clothes.dm @@ -276,11 +276,6 @@ icon_file = 'icons/mob/inhands/clothing/suits_righthand.dmi' json_config = 'code/datums/greyscale/json_configs/jumpsuit_prison_inhand.json' -/datum/greyscale_config/jumpsuit/worn_digi - name = "Jumpsuit Worn (Digitigrate)" - icon_file = 'icons/mob/clothing/under/digi_template.dmi' - json_config = 'code/datums/greyscale/json_configs/jumpsuit_worn_digilegs.json' - /datum/greyscale_config/eth_tunic name = "Ethereal Tunic" icon_file = 'icons/obj/clothing/under/ethereal.dmi' @@ -627,6 +622,14 @@ name = "Waistcoat (Worn)" icon_file = 'icons/mob/clothing/accessories.dmi' +// Digi Stuff + +/datum/greyscale_config/digitigrade + name = "Digitigrade Clothes" + icon_file = 'icons/mob/clothing/digi_template.dmi' + json_config = 'code/datums/greyscale/json_configs/digitigrade.json' + + // // SUIT + HEAD // (Specifically for toggleable suits with hats, i.e. winter coats) diff --git a/code/datums/greyscale/json_configs/digitigrade.json b/code/datums/greyscale/json_configs/digitigrade.json new file mode 100644 index 00000000000..899dff334e4 --- /dev/null +++ b/code/datums/greyscale/json_configs/digitigrade.json @@ -0,0 +1,39 @@ +{ + "jumpsuit_worn": [ + { + "type": "icon_state", + "icon_state": "jumpsuit", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ], + "oversuit_worn": [ + { + "type": "icon_state", + "icon_state": "oversuit", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ], + "sneakers_worn": [ + { + "type": "icon_state", + "icon_state": "shoes_colored", + "blend_mode": "overlay", + "color_ids": [ 1 ] + }, + { + "type": "icon_state", + "icon_state": "shoes_uncolored", + "blend_mode": "overlay" + } + ], + "boots_worn": [ + { + "type": "icon_state", + "icon_state": "boots", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/code/datums/greyscale/json_configs/jumpsuit_worn_digilegs.json b/code/datums/greyscale/json_configs/jumpsuit_worn_digilegs.json deleted file mode 100644 index 9aa201cece3..00000000000 --- a/code/datums/greyscale/json_configs/jumpsuit_worn_digilegs.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "": [ - { - "type": "icon_state", - "icon_state": "jumpsuit", - "blend_mode": "overlay", - "color_ids": [ 1 ] - } - ] -} diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index f32690f334c..b8aec816391 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -39,12 +39,6 @@ ///The config type to use for greyscaled belt overlays. Both this and greyscale_colors must be assigned to work. var/greyscale_config_belt - /// Greyscale config used when generating digitigrade versions of the sprite. - var/digitigrade_greyscale_config_worn - /// Greyscale colors used when generating digitigrade versions of the sprite. - /// Optional - If not set it will default to normal greyscale colors, or approximate them if those are unset as well - var/digitigrade_greyscale_colors - /* !!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!! IF YOU ADD MORE ICON CRAP TO THIS diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 3ecec813a95..1793a212ae3 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -110,6 +110,9 @@ var/mob/M = loc M.update_worn_shoes() +/obj/item/clothing/shoes/generate_digitigrade_icons(icon/base_icon, greyscale_colors) + return icon(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/digitigrade, greyscale_colors), "boots_worn") + /** * adjust_laces adjusts whether our shoes (assuming they can_be_tied) and tied, untied, or knotted * diff --git a/code/modules/clothing/shoes/boots.dm b/code/modules/clothing/shoes/boots.dm index 77e7b2ff369..2dba6ed24fc 100644 --- a/code/modules/clothing/shoes/boots.dm +++ b/code/modules/clothing/shoes/boots.dm @@ -3,6 +3,7 @@ desc = "High speed, low drag combat boots." icon_state = "jackboots" inhand_icon_state = "jackboots" + supports_variations_flags = CLOTHING_DIGITIGRADE_MASK body_parts_covered = FEET|LEGS armor_type = /datum/armor/shoes_combat strip_delay = 40 @@ -45,6 +46,7 @@ desc = "Nanotrasen-issue Security combat boots for combat scenarios or combat situations. All combat, all the time." icon_state = "jackboots" inhand_icon_state = "jackboots" + supports_variations_flags = CLOTHING_DIGITIGRADE_MASK strip_delay = 30 equip_delay_other = 50 resistance_flags = NONE @@ -71,6 +73,7 @@ desc = "Is it just me or is there a pair of jackboots on the floor?" icon_state = "ftc_boots" inhand_icon_state = null + supports_variations_flags = NONE /obj/item/clothing/shoes/jackboots/floortile/Initialize(mapload) . = ..() @@ -81,6 +84,7 @@ desc = "Boots lined with 'synthetic' animal fur." icon_state = "winterboots" inhand_icon_state = null + supports_variations_flags = CLOTHING_DIGITIGRADE_MASK armor_type = /datum/armor/shoes_winterboots cold_protection = FEET|LEGS min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT @@ -131,6 +135,7 @@ icon_state = "workboots" inhand_icon_state = "jackboots" armor_type = /datum/armor/shoes_workboots + supports_variations_flags = CLOTHING_DIGITIGRADE_MASK strip_delay = 20 equip_delay_other = 40 lace_time = 8 SECONDS @@ -155,6 +160,7 @@ icon_state = "rus_shoes" inhand_icon_state = null lace_time = 8 SECONDS + supports_variations_flags = CLOTHING_DIGITIGRADE_MASK /obj/item/clothing/shoes/russian/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/shoes/sneakers.dm b/code/modules/clothing/shoes/sneakers.dm index 0ae1e6e9caa..1fc47accd35 100644 --- a/code/modules/clothing/shoes/sneakers.dm +++ b/code/modules/clothing/shoes/sneakers.dm @@ -9,9 +9,17 @@ greyscale_config_worn = /datum/greyscale_config/sneakers/worn greyscale_config_inhand_left = /datum/greyscale_config/sneakers/inhand_left greyscale_config_inhand_right = /datum/greyscale_config/sneakers/inhand_right + supports_variations_flags = CLOTHING_DIGITIGRADE_MASK flags_1 = IS_PLAYER_COLORABLE_1 interaction_flags_mouse_drop = NEED_HANDS +/obj/item/clothing/shoes/sneakers/get_general_color(icon/base_icon) + var/colors = SSgreyscale.ParseColorString(greyscale_colors) + return colors ? colors[1] : ..() + +/obj/item/clothing/shoes/sneakers/generate_digitigrade_icons(icon/base_icon, greyscale_colors) + return icon(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/digitigrade, greyscale_colors), "sneakers_worn") + /obj/item/clothing/shoes/sneakers/random/Initialize(mapload) . = ..() greyscale_colors = "#" + random_color() + "#" + random_color() diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index ecae343f685..78ea1d2f3b7 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -43,3 +43,7 @@ if(ismob(loc)) var/mob/M = loc M.update_worn_oversuit() + +/obj/item/clothing/suit/generate_digitigrade_icons(icon/base_icon, greyscale_colors) + var/icon/legs = icon(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/digitigrade, greyscale_colors), "oversuit_worn") + return replace_icon_legs(base_icon, legs) diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 85fff72052b..3fa11d2882c 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -9,7 +9,6 @@ interaction_flags_click = NEED_DEXTERITY armor_type = /datum/armor/clothing_under supports_variations_flags = CLOTHING_DIGITIGRADE_MASK - digitigrade_greyscale_config_worn = /datum/greyscale_config/jumpsuit/worn_digi equip_sound = 'sound/items/equip/jumpsuit_equip.ogg' drop_sound = 'sound/items/handling/cloth_drop.ogg' pickup_sound = 'sound/items/handling/cloth_pickup.ogg' @@ -142,6 +141,10 @@ adjusted = DIGITIGRADE_STYLE update_appearance() +/obj/item/clothing/under/generate_digitigrade_icons(icon/base_icon, greyscale_colors) + var/icon/legs = icon(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/digitigrade, greyscale_colors), "jumpsuit_worn") + return replace_icon_legs(base_icon, legs) + /obj/item/clothing/under/equipped(mob/living/user, slot) ..() if((slot & ITEM_SLOT_ICLOTHING) && freshly_laundered) diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index 9ae1c7d63e3..af64ca4e999 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -224,10 +224,12 @@ greyscale_config_inhand_left = null greyscale_config_inhand_right = null greyscale_config_worn = null - digitigrade_greyscale_colors = "#3f3f3f" can_adjust = FALSE flags_1 = NONE +/obj/item/clothing/under/color/rainbow/get_general_color(icon/base_icon) + return "#3f3f3f" + /obj/item/clothing/under/color/jumpskirt/rainbow name = "rainbow jumpskirt" desc = "A multi-colored jumpskirt!" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 70d2a5eeadb..2c428f1c35c 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -33,7 +33,9 @@ desc = "Groovy!" icon_state = "psyche" inhand_icon_state = "p_suit" - digitigrade_greyscale_colors = "#3f3f3f" + +/obj/item/clothing/under/misc/psyche/get_general_color(icon/base_icon) + return "#3f3f3f" /obj/item/clothing/under/misc/vice_officer name = "vice officer's jumpsuit" diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 216275a2390..a6b2f075b8f 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -6,6 +6,7 @@ icon = 'icons/obj/clothing/suits/utility.dmi' worn_icon = 'icons/mob/clothing/suits/utility.dmi' inhand_icon_state = null + supports_variations_flags = CLOTHING_DIGITIGRADE_MASK body_parts_covered = CHEST|GROIN|LEGS|ARMS cold_protection = CHEST|GROIN|LEGS|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT @@ -15,6 +16,9 @@ armor_type = /datum/armor/hooded_explorer resistance_flags = FIRE_PROOF +/obj/item/clothing/suit/hooded/explorer/get_general_color(icon/base_icon) + return "#796755" + /datum/armor/hooded_explorer melee = 30 bullet = 10 diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index 73ce6808339..6227e9558db 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -573,20 +573,70 @@ There are several things that need to be remembered: return icon(female_clothing_icon) -// These coordonates point to roughly somewhere in the middle of the left leg -// Used in approximating what color the pants of clothing should be +/// Modifies a sprite to conform to digitigrade body shapes +/proc/wear_digi_version(icon/base_icon, obj/item/item, key, greyscale_colors) + ASSERT(istype(item), "wear_digi_version: no item passed") + ASSERT(istext(key), "wear_digi_version: no key passed") + if(isnull(greyscale_colors) || length(SSgreyscale.ParseColorString(greyscale_colors)) > 1) + greyscale_colors = item.get_general_color(base_icon) + + var/index = "[key]-[item.type]-[greyscale_colors]" + var/static/list/digitigrade_clothing_cache = list() + var/icon/resulting_icon = digitigrade_clothing_cache[index] + if(!resulting_icon) + resulting_icon = item.generate_digitigrade_icons(base_icon, greyscale_colors) + if(!resulting_icon) + stack_trace("[item.type] is set to generate a masked digitigrade icon, but generate_digitigrade_icons was not implemented (or error'd).") + return base_icon + digitigrade_clothing_cache[index] = fcopy_rsc(resulting_icon) + + return icon(resulting_icon) + +/// Modifies a sprite to replace the legs with a new version +/proc/replace_icon_legs(icon/base_icon, icon/new_legs) + var/static/icon/leg_mask + if(!leg_mask) + leg_mask = icon('icons/mob/clothing/under/masking_helpers.dmi', "digi_leg_mask") + + // cuts the legs off + base_icon.Blend(leg_mask, ICON_SUBTRACT) + // staples the new legs on + base_icon.Blend(new_legs, ICON_OVERLAY) + return base_icon + +/** + * Generates a digitigrade version of this item's worn icon + * + * Arguments: + * * base_icon: The icon to generate the digitigrade icon from + * * greyscale_colors: The greyscale colors to use for the digitigrade icon + * + * Returns an icon that is the digitigrade version of the item's worn icon + * Returns null if the item has no support for digitigrade variations via this method + */ +/obj/item/proc/generate_digitigrade_icons(icon/base_icon, greyscale_colors) + return null + +/** + * Get what color the item is on "average" + * Can be used to approximate what color this item is/should be + * + * Arguments: + * * base_icon: The icon to get the color from + */ +/obj/item/proc/get_general_color(icon/base_icon) + if(greyscale_colors && length(SSgreyscale.ParseColorString(greyscale_colors)) == 1) + return greyscale_colors + return color + +// These coordinates point to the middle of the left leg #define LEG_SAMPLE_X_LOWER 13 #define LEG_SAMPLE_X_UPPER 14 - #define LEG_SAMPLE_Y_LOWER 8 #define LEG_SAMPLE_Y_UPPER 9 -/// Modifies a sprite to conform to digitigrade body shapes -/proc/wear_digi_version(icon/base_icon, key, greyscale_config = /datum/greyscale_config/jumpsuit/worn_digi, greyscale_colors) - ASSERT(key, "wear_digi_version: no key passed") - ASSERT(ispath(greyscale_config, /datum/greyscale_config), "wear_digi_version: greyscale_config is not a valid path (got: [greyscale_config])") - // items with greyscale colors containing multiple colors are invalid - if(isnull(greyscale_colors) || length(SSgreyscale.ParseColorString(greyscale_colors)) > 1) +/obj/item/clothing/get_general_color(icon/base_icon) + if(slot_flags & (ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING)) var/pant_color // approximates the color of the pants by sampling a few pixels in the middle of the left leg for(var/x in LEG_SAMPLE_X_LOWER to LEG_SAMPLE_X_UPPER) @@ -594,37 +644,26 @@ There are several things that need to be remembered: var/xy_color = base_icon.GetPixel(x, y) pant_color = pant_color ? BlendRGB(pant_color, xy_color, 0.5) : xy_color - greyscale_colors = pant_color || "#1d1d1d" // black pants always look good + return pant_color || "#1d1d1d" // black pants always look good - var/index = "[key]-[greyscale_config]-[greyscale_colors]" - var/static/list/digitigrade_clothing_icons = list() - var/icon/digitigrade_clothing_icon = digitigrade_clothing_icons[index] - if(!digitigrade_clothing_icon) - var/static/icon/torso_mask - if(!torso_mask) - torso_mask = icon('icons/mob/clothing/under/masking_helpers.dmi', "digi_torso_mask") - var/static/icon/leg_mask - if(!leg_mask) - leg_mask = icon('icons/mob/clothing/under/masking_helpers.dmi', "digi_leg_mask") - - base_icon.Blend(leg_mask, ICON_SUBTRACT) // cuts the legs off - - var/icon/leg_icon = SSgreyscale.GetColoredIconByType(greyscale_config, greyscale_colors) - leg_icon.Blend(torso_mask, ICON_SUBTRACT) // cuts the torso off - - base_icon.Blend(leg_icon, ICON_OVERLAY) // puts the new legs on - - digitigrade_clothing_icon = fcopy_rsc(base_icon) - digitigrade_clothing_icons[index] = digitigrade_clothing_icon - - return icon(digitigrade_clothing_icon) + return ..() #undef LEG_SAMPLE_X_LOWER #undef LEG_SAMPLE_X_UPPER - #undef LEG_SAMPLE_Y_LOWER #undef LEG_SAMPLE_Y_UPPER +// Points to the tip of the left foot +#define SHOE_SAMPLE_X 11 +#define SHOE_SAMPLE_Y 2 + +/obj/item/clothing/shoes/get_general_color(icon/base_icon) + // just grabs the color of the middle of the left foot + return base_icon.GetPixel(SHOE_SAMPLE_X, SHOE_SAMPLE_Y) || "#1d1d1d" + +#undef SHOE_SAMPLE_X +#undef SHOE_SAMPLE_Y + /mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers) var/list/out = new for(var/i in 1 to TOTAL_LAYERS) @@ -774,9 +813,9 @@ generate/load female uniform sprites matching all previously decided variables if(!isinhands && is_digi && (supports_variations_flags & CLOTHING_DIGITIGRADE_MASK)) building_icon = wear_digi_version( base_icon = building_icon || icon(file2use, t_state), + item = src, key = "[t_state]-[file2use]-[female_uniform]", - greyscale_config = digitigrade_greyscale_config_worn || greyscale_config_worn, - greyscale_colors = digitigrade_greyscale_colors || greyscale_colors || color, + greyscale_colors = greyscale_colors, ) if(building_icon) standing = mutable_appearance(building_icon, layer = -layer2use) diff --git a/code/modules/unit_tests/screenshots/screenshot_digi_leg_test.png b/code/modules/unit_tests/screenshots/screenshot_digi_leg_test.png index 1ca452de089..3907b46b870 100644 Binary files a/code/modules/unit_tests/screenshots/screenshot_digi_leg_test.png and b/code/modules/unit_tests/screenshots/screenshot_digi_leg_test.png differ diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_ashwalker.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_ashwalker.png index 3437280e851..9c05ab07e5f 100644 Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_ashwalker.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_ashwalker.png differ diff --git a/icons/mob/clothing/digi_template.dmi b/icons/mob/clothing/digi_template.dmi new file mode 100644 index 00000000000..319bd875041 Binary files /dev/null and b/icons/mob/clothing/digi_template.dmi differ diff --git a/icons/mob/clothing/under/digi_template.dmi b/icons/mob/clothing/under/digi_template.dmi deleted file mode 100644 index 0c9db80eb1c..00000000000 Binary files a/icons/mob/clothing/under/digi_template.dmi and /dev/null differ diff --git a/icons/mob/clothing/under/masking_helpers.dmi b/icons/mob/clothing/under/masking_helpers.dmi index dfbec7d1cb8..26e1cc44668 100644 Binary files a/icons/mob/clothing/under/masking_helpers.dmi and b/icons/mob/clothing/under/masking_helpers.dmi differ