Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tubby Cow: better clothing coverage for bovines, via filters #17043

Merged
merged 24 commits into from
Dec 23, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
84 changes: 84 additions & 0 deletions code/datums/mutantraces.dm
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ ABSTRACT_TYPE(/datum/mutantrace)
for (var/category in src.clothing_icons)
src.clothing_icon_states[category] = icon_states(src.clothing_icons[category], 1)

/// Called by /mob/living/carbon/human/update_clothing()'s slot-specific sub-procs.
/// Each sub-proc passes its obj to this proc, which you can then operate on.
/// Should return a filter or list of filters, to be added to the obj's wear_image.filters
proc/apply_clothing_filters(var/obj/item/worn)
. = null

proc/say_filter(var/message)
return message

Expand Down Expand Up @@ -2087,6 +2093,25 @@ ABSTRACT_TYPE(/datum/mutantrace)

return

/obj/effect/distort/cow_distorts
icon = 'icons/mob/cow.dmi'

/obj/effect/distort/cow_distorts/under // extends jumpsuit icons to cover the udder
icon_state = "under_distort"
/obj/effect/distort/cow_distorts/suit // covers udder and hand gaps, adapts icon state for different suit styles
icon_state = "suit_distort"
/obj/effect/distort/cow_distorts/belt // udder, hand gaps
icon_state = "belt_distort"
/obj/effect/distort/cow_distorts/satchel // covers hand gap in east dir only
icon_state = "satchel_distort"

/obj/effect/rt/cow_gloves_mask // trims far-side glove sprites so they don't render on top of the udder
icon = 'icons/mob/cow.dmi'
icon_state = "gloves_mask"
/obj/effect/rt/cow_backpack_mask // trims the far-side backpack strap, so it appears to hide behind the udder
icon = 'icons/mob/cow.dmi'
icon_state = "backpack_mask"

/datum/mutantrace/cow
name = "cow"
icon = 'icons/mob/cow.dmi'
Expand Down Expand Up @@ -2121,6 +2146,14 @@ ABSTRACT_TYPE(/datum/mutantrace)
self_click_fluff = list("fur", "hooves", "horns")
blood_id = "milk"

var/clothes_filters_active = TRUE // can toggle the filters with a custom mutantrace emote: *udder
var/obj/effect/distort/cow_distorts/under/distort_under = new
var/obj/effect/distort/cow_distorts/suit/distort_suit = new
var/obj/effect/distort/cow_distorts/belt/distort_belt = new
var/obj/effect/distort/cow_distorts/satchel/distort_satchel = new
var/obj/effect/rt/cow_gloves_mask/mask_gloves = new
var/obj/effect/rt/cow_backpack_mask/mask_backpack = new

on_attach(var/mob/living/carbon/human/H)
..()
if(ishuman(src.mob))
Expand All @@ -2131,14 +2164,61 @@ ABSTRACT_TYPE(/datum/mutantrace)
src.mob.kickMessage = "stomps"
src.mob.traitHolder?.addTrait("hemophilia")

src.mob.vis_contents += src.distort_under
src.mob.vis_contents += src.distort_suit
src.mob.vis_contents += src.distort_belt
src.mob.vis_contents += src.distort_satchel
src.mob.vis_contents += src.mask_gloves
src.mob.vis_contents += src.mask_backpack
kbsmilk marked this conversation as resolved.
Show resolved Hide resolved

disposing()
if (ishuman(src.mob))
var/mob/living/carbon/human/H = src.mob
if (H.mob_flags & SHOULD_HAVE_A_TAIL)
H.mob_flags &= ~SHOULD_HAVE_A_TAIL
H.kickMessage = initial(H.kickMessage)
H.traitHolder?.removeTrait("hemophilia")

src.mob.vis_contents -= src.distort_under
src.mob.vis_contents -= src.distort_suit
src.mob.vis_contents -= src.distort_belt
src.mob.vis_contents -= src.distort_satchel
src.mob.vis_contents -= src.mask_gloves
src.mob.vis_contents -= src.mask_backpack
. = ..()

apply_clothing_filters(var/obj/item/worn)
. = ..()
if (!src.clothes_filters_active) return
var/list/output = list()

if (istype(worn, /obj/item/clothing/suit))
var/obj/item/clothing/cloth = worn
var/hands = (cloth.hides_from_examine & C_GLOVES || src.mob.gloves) ? "" : "_hands" // armor layers over gloves X)

if (icon(cloth.wear_image_icon, cloth.wear_image.icon_state).GetPixel(21, 18, dir = EAST))
// check if a pixel is over the udder, mostly space/diving suits and some voluminous coats
src.distort_suit.icon_state = "suit_wide[hands]_distort"
else if (!icon(cloth.wear_image_icon, cloth.wear_image.icon_state).GetPixel(19, 18, dir = EAST))
// check if it's possibly an open jacket, like black/jean/winter jackets or lab/captain coat
src.distort_suit.icon_state = "suit_thin[hands]_distort"
else // everything else, generic and mostly decent
src.distort_suit.icon_state = "suit[hands]_distort"

output += filter(type="displace", render_source = src.distort_suit.render_target, size = 127)
else if (istype(worn, /obj/item/clothing/gloves))
output += filter(type="alpha", render_source = src.mask_gloves.render_target, flags = MASK_INVERSE)
else if (istype(worn, /obj/item/storage/backpack/satchel))
if (src.mob.gloves) return // layers layers layers
output += filter(type="displace", render_source = src.distort_satchel.render_target, size = 127)
else if (istype(worn, /obj/item/storage/backpack))
output += filter(type="alpha", render_source = src.mask_backpack.render_target, flags = MASK_INVERSE)
else if (istype(worn, /obj/item/storage/belt) || istype(worn, /obj/item/storage/fanny))
output += filter(type="displace", render_source = src.distort_belt.render_target, size = 127)
else if (istype(worn, /obj/item/clothing/under))
output += filter(type="displace", render_source = src.distort_under.render_target, size = 127)

return output

say_filter(var/message)
.= replacetext(message, "cow", "human")
Expand All @@ -2155,6 +2235,10 @@ ABSTRACT_TYPE(/datum/mutantrace)
if ("milk")
if (src.mob.emote_check(voluntary))
.= release_milk()
if ("udder")
src.clothes_filters_active = !src.clothes_filters_active
boutput(src.mob, src.clothes_filters_active ? "Bovine-specific clothes filters activated." : "Disabled bovine-specific clothes filters.")
src.mob.update_clothing()
else
.= ..()

Expand Down
27 changes: 15 additions & 12 deletions code/mob/living/carbon/human/procs/update_icon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@
var/image/suit_image
wear_sanity_check(src.w_uniform)
suit_image = src.w_uniform.wear_image
suit_image.filters = src.w_uniform.filters.Copy()
suit_image.filters = src.w_uniform.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.w_uniform)
//suit_image.filters += src.mutantrace?.apply_clothing_filters()
kbsmilk marked this conversation as resolved.
Show resolved Hide resolved

var/wear_state = src.w_uniform.wear_state || src.w_uniform.icon_state
if (wear_state in src.mutantrace?.clothing_icon_states?["uniform"])
suit_image.icon = src.mutantrace.clothing_icons["uniform"]
Expand Down Expand Up @@ -159,7 +161,7 @@
src.wear_id.wear_image.layer = src.wear_id.wear_layer
src.wear_id.wear_image.color = src.wear_id.color
src.wear_id.wear_image.alpha = src.wear_id.alpha
src.wear_id.wear_image.filters = src.wear_id.filters.Copy()
src.wear_id.wear_image.filters = src.wear_id.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.wear_id)
src.UpdateOverlays(src.wear_id.wear_image, "wear_id")
else
src.UpdateOverlays(null, "wear_id")
Expand All @@ -171,7 +173,7 @@
var/icon_name = src.gloves.wear_state || src.gloves.item_state || src.gloves.icon_state
var/no_offset = FALSE
src.gloves.wear_image.layer = src.gloves.wear_layer
src.gloves.wear_image.filters = src.gloves.filters.Copy()
src.gloves.wear_image.filters = src.gloves.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.gloves)

if (src.limbs && src.limbs.l_arm && src.limbs.l_arm.accepts_normal_human_overlays) //src.bioHolder && !src.bioHolder.HasEffect("robot_left_arm"))
var/icon_local = (src.gloves.which_hands & GLOVE_HAS_LEFT) ? icon_name : "transparent"
Expand Down Expand Up @@ -247,12 +249,12 @@
else
src.shoes.wear_image.icon = src.shoes.wear_image_icon
var/image/right_shoe_overlay = image(src.shoes.wear_image.icon, "right_[wear_state]")
right_shoe_overlay.filters = src.shoes.filters.Copy()
right_shoe_overlay.filters = src.shoes.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.shoes)
src.shoes.wear_image.overlays += right_shoe_overlay


if(shoes_count)
src.shoes.wear_image.filters = src.shoes.filters.Copy()
src.shoes.wear_image.filters = src.shoes.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.shoes)
src.UpdateOverlays(src.shoes.wear_image, "wear_shoes")
else
src.UpdateOverlays(null, "wear_shoes")
Expand All @@ -264,7 +266,8 @@
if (src.wear_suit)
wear_sanity_check(src.wear_suit)
src.wear_suit.wear_image.layer = src.wear_suit.wear_layer
src.wear_suit.wear_image.filters = src.wear_suit.filters.Copy()
src.wear_suit.wear_image.filters = src.wear_suit.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.wear_suit)
//src.wear_suit.wear_image.filters += src.mutantrace?.apply_clothing_filters(src.wear_suit)

var/wear_state = src.wear_suit.wear_state || src.wear_suit.icon_state
if (wear_state in src.mutantrace?.clothing_icon_states?["overcoats"])
Expand Down Expand Up @@ -328,7 +331,7 @@
src.back.wear_image.color = src.back.color
src.back.wear_image.alpha = src.back.alpha
src.back.update_wear_image(src, src.back.wear_image.icon != src.back.wear_image_icon)
src.back.wear_image.filters = src.back.filters.Copy()
src.back.wear_image.filters = src.back.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.back)
src.UpdateOverlays(src.back.wear_image, "wear_back")

if (src.back.worn_material_texture_image != null)
Expand Down Expand Up @@ -361,7 +364,7 @@
src.glasses.wear_image.color = src.glasses.color
src.glasses.wear_image.alpha = src.glasses.alpha
src.glasses.update_wear_image(src, src.glasses.wear_image.icon != src.glasses.wear_image_icon)
src.glasses.wear_image.filters = src.glasses.filters.Copy()
src.glasses.wear_image.filters = src.glasses.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.glasses)
src.UpdateOverlays(src.glasses.wear_image, "wear_glasses")
if (src.glasses.worn_material_texture_image != null)
src.glasses.worn_material_texture_image.layer = src.glasses.wear_image.layer + 0.1
Expand Down Expand Up @@ -391,7 +394,7 @@
src.ears.wear_image.pixel_y = head_offset
src.ears.wear_image.color = src.ears.color
src.ears.wear_image.alpha = src.ears.alpha
src.ears.wear_image.filters = src.ears.filters.Copy()
src.ears.wear_image.filters = src.ears.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.ears)
src.UpdateOverlays(src.ears.wear_image, "wear_ears")
if (src.ears.worn_material_texture_image != null)
src.ears.worn_material_texture_image.layer = src.ears.wear_image.layer + 0.1
Expand Down Expand Up @@ -425,7 +428,7 @@
src.wear_mask.wear_image.color = src.wear_mask.color
src.wear_mask.wear_image.alpha = src.wear_mask.alpha
src.wear_mask.update_wear_image(src, src.wear_mask.wear_image.icon != src.wear_mask.wear_image_icon)
src.wear_mask.wear_image.filters = src.wear_mask.filters.Copy()
src.wear_mask.wear_image.filters = src.wear_mask.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.wear_mask)
src.UpdateOverlays(src.wear_mask.wear_image, "wear_mask")
if (src.wear_mask.worn_material_texture_image != null)
src.wear_mask.worn_material_texture_image.layer = src.wear_mask.wear_image.layer + 0.1
Expand Down Expand Up @@ -459,7 +462,7 @@
src.head.wear_image.color = src.head.color
src.head.wear_image.alpha = src.head.alpha
src.head.update_wear_image(src, src.head.wear_image.icon != src.head.wear_image_icon)
src.head.wear_image.filters = src.head.filters.Copy()
src.head.wear_image.filters = src.head.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.head)
src.UpdateOverlays(src.head.wear_image, "wear_head")
if (src.head.worn_material_texture_image != null)
src.head.worn_material_texture_image.layer = src.head.wear_image.layer + 0.1
Expand Down Expand Up @@ -492,7 +495,7 @@
src.belt.wear_image.layer = MOB_BELT_LAYER
src.belt.wear_image.color = src.belt.color
src.belt.wear_image.alpha = src.belt.alpha
src.belt.wear_image.filters = src.belt.filters.Copy()
src.belt.wear_image.filters = src.belt.filters.Copy() + src.mutantrace?.apply_clothing_filters(src.belt)
src.UpdateOverlays(src.belt.wear_image, "wear_belt")
if (src.belt.worn_material_texture_image != null)
src.belt.worn_material_texture_image.layer = src.belt.wear_image.layer + 0.1
Expand Down
7 changes: 7 additions & 0 deletions code/obj/effect.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,12 @@
..()
src.render_target = "*\ref[src]"

/obj/effect/rt
kbsmilk marked this conversation as resolved.
Show resolved Hide resolved
vis_flags = VIS_INHERIT_DIR

New()
..()
src.render_target = "*\ref[src]"

/obj/effect/artifact_glowie
appearance_flags = PIXEL_SCALE | RESET_COLOR | KEEP_TOGETHER
Binary file modified icons/mob/cow.dmi
Binary file not shown.