diff --git a/code/_helpers/icons_vr.dm b/code/_helpers/icons_vr.dm index be5de68e82d..60765578e71 100644 --- a/code/_helpers/icons_vr.dm +++ b/code/_helpers/icons_vr.dm @@ -42,4 +42,18 @@ for(var/x_pixel = 1 to I.Width()) if (I.GetPixel(x_pixel, y_pixel)) return y_pixel - 1 - return null \ No newline at end of file + return null + +//Standard behaviour is to cut pixels from the main icon that are covered by pixels from the mask icon unless passed mask_ready, see below. +/proc/get_icon_difference(var/icon/main, var/icon/mask, var/mask_ready) + /*You should skip prep if the mask is already sprited properly. This significantly improves performance by eliminating most of the realtime icon work. + e.g. A 'ready' mask is a mask where the part you want cut out is missing (no pixels, 0 alpha) from the sprite, and everything else is solid white.*/ + + if(istype(main) && istype(mask)) + if(!mask_ready) //Prep the mask if we're using a regular old sprite and not a special-made mask. + mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible. + mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white. + mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white background pixels. + + main.AddAlphaMask(mask) //Make the pixels in the main icon that are in the transparent zone of the mask icon also vanish (fully transparent). + return main diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 591da027570..4e39439c124 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -716,7 +716,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. icon = 'icons/obj/device.dmi' //Worn icon generation for on-mob sprites -/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer) +/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null) //VOREStation edit - add 'clip mask' argument. //Get the required information about the base icon var/icon/icon2use = get_worn_icon_file(body_type = body_type, slot_name = slot_name, default_icon = default_icon, inhands = inhands) var/state2use = get_worn_icon_state(slot_name = slot_name) @@ -738,6 +738,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. if(!inhands) apply_custom(standing_icon) //Pre-image overridable proc to customize the thing apply_addblends(icon2use,standing_icon) //Some items have ICON_ADD blend shaders + if(istype(clip_mask)) //VOREStation Edit - For taur bodies/tails clipping off parts of uniforms and suits. + standing_icon = get_icon_difference(standing_icon, clip_mask, 1) var/image/standing = image(standing_icon) standing.alpha = alpha diff --git a/code/modules/clothing/clothing_vr.dm b/code/modules/clothing/clothing_vr.dm index 9c04fc98413..b6e387c9bf9 100644 --- a/code/modules/clothing/clothing_vr.dm +++ b/code/modules/clothing/clothing_vr.dm @@ -126,7 +126,7 @@ return ..() // Taur suits need to be shifted so its centered on their taur half. -/obj/item/clothing/suit/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0) +/obj/item/clothing/suit/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0,var/icon/clip_mask) var/image/standing = ..() if(taurized) //Special snowflake var on suits standing.pixel_x = -16 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 249bfb5a91d..169f091c0c8 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -246,7 +246,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() for(var/organ_tag in species.has_limbs) var/obj/item/organ/external/part = organs_by_name[organ_tag] - if(isnull(part) || part.is_stump()) + if(isnull(part) || part.is_stump() || part.is_hidden_by_tail()) //VOREStation Edit allowing tails to prevent bodyparts rendering, granting more spriter freedom for taur/digitigrade stuff. icon_key += "0" continue if(part) @@ -289,7 +289,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() base_icon = chest.get_icon() for(var/obj/item/organ/external/part in organs) - if(isnull(part) || part.is_stump()) + if(isnull(part) || part.is_stump() || part.is_hidden_by_tail()) //VOREStation Edit allowing tails to prevent bodyparts rendering, granting more spriter freedom for taur/digitigrade stuff. continue var/icon/temp = part.get_icon(skeleton) //That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST @@ -576,7 +576,15 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() return //Wearing a suit that prevents uniform rendering //Build a uniform sprite - overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER) + //VOREStation Edit start. + var/icon/c_mask = null + if(tail_style && tail_style.clip_mask_icon && tail_style.clip_mask_state) + var/obj/item/clothing/suit/S = wear_suit + if(!(wear_suit && ((wear_suit.flags_inv & HIDETAIL) || (istype(S) && S.taurized)))) //Clip the lower half of the suit off using the tail's clip mask. + c_mask = new /icon(tail_style.clip_mask_icon, tail_style.clip_mask_state) + overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER, clip_mask = c_mask) + //VOREStation Edit end. + apply_layer(UNIFORM_LAYER) /mob/living/carbon/human/update_inv_wear_id() @@ -658,6 +666,12 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() if(!shoes || (wear_suit && wear_suit.flags_inv & HIDESHOES) || (w_uniform && w_uniform.flags_inv & HIDESHOES)) return //Either nothing to draw, or it'd be hidden. + //VOREStation Edit + for(var/f in list(BP_L_FOOT, BP_R_FOOT)) + var/obj/item/organ/external/foot/foot = get_organ(f) + if(istype(foot) && foot.is_hidden_by_tail()) //If either foot is hidden by the tail, don't render footwear. + return + //Allow for shoe layer toggle nonsense var/shoe_layer = SHOES_LAYER if(istype(shoes, /obj/item/clothing/shoes)) @@ -741,12 +755,18 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() // Part of splitting the suit sprites up var/iconFile = INV_SUIT_DEF_ICON + var/obj/item/clothing/suit/S //VOREStation edit - break this var out a level for use below. if(istype(wear_suit, /obj/item/clothing/suit)) - var/obj/item/clothing/suit/S = wear_suit + S = wear_suit if(S.update_icon_define) iconFile = S.update_icon_define - overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = iconFile, default_layer = SUIT_LAYER) + //VOREStation Edit start. + var/icon/c_mask = null + if((tail_style && tail_style.clip_mask_icon && tail_style.clip_mask_state) && !(wear_suit.flags_inv & HIDETAIL) && !(S && S.taurized)) //Clip the lower half of the suit off using the tail's clip mask. + c_mask = new /icon(tail_style.clip_mask_icon, tail_style.clip_mask_state) + overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(src), slot_name = slot_wear_suit_str, default_icon = iconFile, default_layer = SUIT_LAYER, clip_mask = c_mask) + //VOREStation Edit end. apply_layer(SUIT_LAYER) @@ -921,7 +941,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() var/t_state = "[species.get_tail(src)]_once" var/used_tail_layer = tail_alt ? TAIL_LAYER_ALT : TAIL_LAYER // VOREStation Edit - Alt Tail Layer - + var/image/tail_overlay = overlays_standing[used_tail_layer] // VOREStation Edit - Alt Tail Layer if(tail_overlay && tail_overlay.icon_state == t_state) return //let the existing animation finish @@ -931,7 +951,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() spawn(20) //check that the animation hasn't changed in the meantime if(overlays_standing[used_tail_layer] == tail_overlay && tail_overlay.icon_state == t_state) // VOREStation Edit - Alt Tail Layer - animate_tail_stop() + animate_tail_stop() /mob/living/carbon/human/proc/animate_tail_start() if(QDESTROYING(src)) @@ -972,7 +992,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() if(vr_wing_image) vr_wing_image.layer = BODY_LAYER+WING_LAYER overlays_standing[WING_LAYER] = vr_wing_image - + apply_layer(WING_LAYER) // VOREStation Edit end diff --git a/code/modules/organs/organ_external_vr.dm b/code/modules/organs/organ_external_vr.dm index 0e3fb07d9ee..491cce94287 100644 --- a/code/modules/organs/organ_external_vr.dm +++ b/code/modules/organs/organ_external_vr.dm @@ -13,3 +13,7 @@ min_broken_damage = o_min_broken_damage else return ..() + +/obj/item/organ/external/proc/is_hidden_by_tail() + if(owner && owner.tail_style && owner.tail_style.hide_body_parts && (organ_tag in owner.tail_style.hide_body_parts)) + return 1 \ No newline at end of file diff --git a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm index 5becc226655..04e0baeaf83 100644 --- a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm @@ -153,6 +153,9 @@ //Messages for smalls moving under larges var/msg_owner_stepunder = "%owner runs between your legs." //Weird becuase in the case this is used, %owner is the 'bumper' (src) var/msg_prey_stepunder = "You run between %prey's legs." //Same, inverse + hide_body_parts = list(BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT) //Exclude pelvis just in case. + clip_mask_icon = 'icons/mob/vore/taurs_vr.dmi' + clip_mask_state = "taur_clip_mask_def" //Used to clip off the lower part of suits & uniforms. /datum/sprite_accessory/tail/taur/roiz_long_lizard // Not ACTUALLY a taur, but it uses 32x64 so it wouldn't fit in tails.dmi, and having it as a tail bugs up the sprite. name = "Long Lizard Tail (Roiz Lizden)" @@ -438,6 +441,7 @@ ckeys_allowed = list("natje") do_colouration = 0 can_ride = 0 + clip_mask_state = "taur_clip_mask_alraune" msg_prey_stepunder = "You run between %prey's vines." @@ -469,11 +473,13 @@ do_colouration = 1 extra_overlay = "alraunecolor_markings" extra_overlay_w = "alraunecolor_closed_markings" + clip_mask_state = "taur_clip_mask_alraune" /datum/sprite_accessory/tail/taur/wasp name = "Wasp (dual color)" icon_state = "wasp_s" extra_overlay = "wasp_markings" + clip_mask_state = "taur_clip_mask_wasp" msg_owner_disarm_run = "You quickly push %prey to the ground with your leg!" msg_prey_disarm_run = "%owner pushes you down to the ground with their leg!" diff --git a/code/modules/vore/appearance/sprite_accessories_vr.dm b/code/modules/vore/appearance/sprite_accessories_vr.dm index 50b8d763a2f..89f5e9c7464 100644 --- a/code/modules/vore/appearance/sprite_accessories_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_vr.dm @@ -653,6 +653,9 @@ var/desc = "You should not see this..." var/ani_state // State when wagging/animated var/extra_overlay_w // Wagging state for extra overlay + var/list/hide_body_parts = list() //Uses organ tag defines. Bodyparts in this list do not have their icons rendered, allowing for more spriter freedom when doing taur/digitigrade stuff. + var/icon/clip_mask_icon = null //Icon file used for clip mask. + var/clip_mask_state = null //Icon state to generate clip mask. Clip mask is used to 'clip' off the lower part of clothing such as jumpsuits & full suits. /datum/sprite_accessory/tail/invisible name = "hide species-sprite tail" @@ -950,6 +953,9 @@ icon_state = "satyr" color_blend_mode = ICON_MULTIPLY do_colouration = 1 + hide_body_parts = list(BP_L_LEG, BP_L_FOOT, BP_R_LEG, BP_R_FOOT) //Exclude pelvis just in case. + clip_mask_icon = 'icons/mob/vore/taurs_vr.dmi' + clip_mask_state = "taur_mask_def" //Used to clip off the lower part of suits & uniforms. /datum/sprite_accessory/tail/tailmaw name = "tailmaw, colorable" diff --git a/icons/mob/vore/taurs_vr.dmi b/icons/mob/vore/taurs_vr.dmi index 568523a47ca..3d5b2423d99 100644 Binary files a/icons/mob/vore/taurs_vr.dmi and b/icons/mob/vore/taurs_vr.dmi differ