diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index a463510a438..a632a7dd222 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -63,6 +63,12 @@ /// Sent to a limb when something *attempts* to change its surgery state (old_state, new_state, changed_states) #define COMSIG_BODYPART_UPDATING_SURGERY_STATE "bodypart_updating_surgery_state" +/// Called from /obj/item/bodypart/proc/get_limb_icon(dropped, mob/living/carbon/update_on) : (list/limb_icons, dropped, mob/living/carbon/update_on) +#define COMSIG_BODYPART_GET_LIMB_ICON "bodypart_get_limb_icon" + +/// Called from /obj/item/bodypart/proc/generate_icon_key() : (list/icon_keys) +#define COMSIG_BODYPART_GENERATE_ICON_KEY "bodypart_generate_icon_key" + ///from /item/organ/proc/Insert() (/obj/item/organ/) #define COMSIG_CARBON_GAIN_ORGAN "carbon_gain_organ" ///from /item/organ/proc/Remove() (/obj/item/organ/) diff --git a/code/datums/elements/blood_limb_overlay.dm b/code/datums/elements/blood_limb_overlay.dm new file mode 100644 index 00000000000..0738bc16b13 --- /dev/null +++ b/code/datums/elements/blood_limb_overlay.dm @@ -0,0 +1,39 @@ +/// An element which adds a blood overlay to limbs its attached to +/datum/element/blood_limb_overlay + +/datum/element/blood_limb_overlay/Attach(datum/target) + . = ..() + if (!isbodypart(target)) + return ELEMENT_INCOMPATIBLE + RegisterSignal(target, COMSIG_BODYPART_GET_LIMB_ICON, PROC_REF(on_limb_icon)) + RegisterSignal(target, COMSIG_BODYPART_GENERATE_ICON_KEY, PROC_REF(on_icon_key)) + +/datum/element/blood_limb_overlay/Detach(datum/source) + . = ..() + UnregisterSignal(source, list(COMSIG_BODYPART_GET_LIMB_ICON, COMSIG_BODYPART_GENERATE_ICON_KEY)) + +/datum/element/blood_limb_overlay/proc/on_limb_icon(obj/item/bodypart/source, list/limb_icons, dropped, mob/living/carbon/update_on) + SIGNAL_HANDLER + + if (!LAZYLEN(source.blood_dna_info) || source.is_invisible) + return + + var/image/limb = limb_icons[1] + var/image/blood_visual = image(limb.icon, "[limb.icon_state]_blood", dir = (dropped ? SOUTH : null)) + // We need to convert it to HSV and then adjust the colors to make them look brighter on the grayscale blood overlay + var/list/target_color = rgb2num(get_color_from_blood_list(source.blood_dna_info), COLORSPACE_HSV) + blood_visual.color = rgb(target_color[1], ceil(target_color[2] * 0.4), clamp(ceil(target_color[3] * 1.33), 0, 100), space = COLORSPACE_HSV) + limb.overlays += blood_visual + if (!source.aux_zone) + return + + var/image/aux = limb_icons[2] + var/image/aux_blood_visual = image(aux.icon, "[aux.icon_state]_blood", dir = (dropped ? SOUTH : null)) + aux_blood_visual.color = blood_visual.color + aux.overlays += aux_blood_visual + +/datum/element/blood_limb_overlay/proc/on_icon_key(obj/item/bodypart/source, list/icon_keys) + SIGNAL_HANDLER + + if (LAZYLEN(source.blood_dna_info) && !source.is_invisible) + icon_keys += "-blood-[get_color_from_blood_list(source.blood_dna_info)]" diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index cf17720ee6e..19d5039de92 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -537,6 +537,7 @@ if(ishuman(owner)) var/mob/living/carbon/human/human_owner = owner . += "-[human_owner.mob_height]" + SEND_SIGNAL(src, COMSIG_BODYPART_GENERATE_ICON_KEY, .) return . ///Generates a cache key specifically for husks diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 04005ff4eff..475cb1ffcd3 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -1264,19 +1264,6 @@ icon_state = "" //to erase the default sprite, we're building the visual aspects of the bodypart through overlays alone. . = list() - - if(dropped && dmg_overlay_type) - if(brutestate) - // divided into two overlays: one that gets colored and one that doesn't. - var/image/brute_blood_overlay = image('icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_[brutestate]0", -DAMAGE_LAYER, dir = SOUTH) - brute_blood_overlay.color = get_color_from_blood_list(update_on ? update_on.get_blood_dna_list() : blood_dna_info) // living mobs can just get it fresh, dropped limbs use blood_dna_info - var/mutable_appearance/brute_damage_overlay = mutable_appearance('icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_[brutestate]0_overlay", -DAMAGE_LAYER, appearance_flags = RESET_COLOR) - if(brute_damage_overlay) - brute_blood_overlay.overlays += brute_damage_overlay - . += brute_blood_overlay - if(burnstate) - . += image('icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_0[burnstate]", -DAMAGE_LAYER, dir = SOUTH) - var/image_dir = null if (dropped) image_dir = SOUTH @@ -1284,6 +1271,7 @@ // Handles invisibility (not alpha or actual invisibility but invisibility) if(is_invisible) . += image(icon_invisible, "invisible_[body_zone]", -BODYPARTS_LAYER, dir = image_dir) + SEND_SIGNAL(src, COMSIG_BODYPART_GET_LIMB_ICON, ., dropped, update_on) return . // Normal non-husk handling @@ -1307,6 +1295,18 @@ aux = image(limb.icon, "[limb_id]_[aux_zone]", -aux_layer, dir = image_dir) . += aux + if(dropped && dmg_overlay_type) + if(brutestate) + // divided into two overlays: one that gets colored and one that doesn't. + var/image/brute_blood_overlay = image('icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_[brutestate]0", -DAMAGE_LAYER, dir = SOUTH) + brute_blood_overlay.color = get_color_from_blood_list(update_on ? update_on.get_blood_dna_list() : blood_dna_info) // living mobs can just get it fresh, dropped limbs use blood_dna_info + var/mutable_appearance/brute_damage_overlay = mutable_appearance('icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_[brutestate]0_overlay", -DAMAGE_LAYER, appearance_flags = RESET_COLOR) + if(brute_damage_overlay) + brute_blood_overlay.overlays += brute_damage_overlay + . += brute_blood_overlay + if(burnstate) + . += image('icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_0[burnstate]", -DAMAGE_LAYER, dir = SOUTH) + if(is_husked) . += huskify_image(thing_to_husk = limb) if(aux) @@ -1357,6 +1357,7 @@ // And finally put bodypart_overlays on if not husked if(is_husked) + SEND_SIGNAL(src, COMSIG_BODYPART_GET_LIMB_ICON, ., dropped, update_on) return . // Draw external organs like horns and frills @@ -1383,6 +1384,8 @@ for(var/datum/layer in .) overlay.modify_bodypart_appearance(layer) + + SEND_SIGNAL(src, COMSIG_BODYPART_GET_LIMB_ICON, ., dropped, update_on) return . /obj/item/bodypart/proc/huskify_image(image/thing_to_husk) diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm index 8ff6971118e..c504f51c38a 100644 --- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm @@ -435,10 +435,18 @@ // These are always disabled disabling_threshold_percentage = 0 +/obj/item/bodypart/head/skeleton/nonfunctional/Initialize(mapload) + . = ..() + AddElement(/datum/element/blood_limb_overlay) + /obj/item/bodypart/chest/skeleton/nonfunctional limb_id = BODYPART_ID_BONE disabling_threshold_percentage = 0 +/obj/item/bodypart/chest/skeleton/nonfunctional/Initialize(mapload) + . = ..() + AddElement(/datum/element/blood_limb_overlay) + /obj/item/bodypart/chest/skeleton/nonfunctional/on_adding(mob/living/carbon/new_owner) . = ..() // Treat people with bone chests as husks for all purposes for now @@ -453,18 +461,34 @@ limb_id = BODYPART_ID_BONE disabling_threshold_percentage = 0 +/obj/item/bodypart/arm/left/skeleton/nonfunctional/Initialize(mapload) + . = ..() + AddElement(/datum/element/blood_limb_overlay) + /obj/item/bodypart/arm/right/skeleton/nonfunctional limb_id = BODYPART_ID_BONE disabling_threshold_percentage = 0 +/obj/item/bodypart/arm/right/skeleton/nonfunctional/Initialize(mapload) + . = ..() + AddElement(/datum/element/blood_limb_overlay) + /obj/item/bodypart/leg/left/skeleton/nonfunctional limb_id = BODYPART_ID_BONE disabling_threshold_percentage = 0 +/obj/item/bodypart/leg/left/skeleton/nonfunctional/Initialize(mapload) + . = ..() + AddElement(/datum/element/blood_limb_overlay) + /obj/item/bodypart/leg/right/skeleton/nonfunctional limb_id = BODYPART_ID_BONE disabling_threshold_percentage = 0 +/obj/item/bodypart/leg/right/skeleton/nonfunctional/Initialize(mapload) + . = ..() + AddElement(/datum/element/blood_limb_overlay) + ///MUSHROOM /obj/item/bodypart/head/mushroom limb_id = SPECIES_MUSHROOM diff --git a/icons/mob/human/bodyparts.dmi b/icons/mob/human/bodyparts.dmi index 7fd40bb0bf2..b37d44f6f8b 100644 Binary files a/icons/mob/human/bodyparts.dmi and b/icons/mob/human/bodyparts.dmi differ diff --git a/tgstation.dme b/tgstation.dme index bf358c3912d..3c6d326a00f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1508,6 +1508,7 @@ #include "code\datums\elements\befriend_petting.dm" #include "code\datums\elements\block_turf_fingerprints.dm" #include "code\datums\elements\blocks_explosives.dm" +#include "code\datums\elements\blood_limb_overlay.dm" #include "code\datums\elements\blood_reagent.dm" #include "code\datums\elements\body_temp_sensitive.dm" #include "code\datums\elements\bombable_turf.dm"