Teshari Specific Limb Damage States and Bloody Clothing (#6038)

## About The Pull Request
Teshari have long had to deal with ill-fitting overlays applied to them.
I have chosen to bite the bullet and do the labour by creating species
specific states for:
- bloody clothes
- damaged clothes
- body wounds
- bleeding animations

How it works is simple: if our icon override exists for our species, we
use it. If it doesn't exist, we default back to the original. What this
means is that future species overrides can be added without code
changes.

## Why It's Good For The Game
<img width="91" height="85" alt="image"
src="https://github.com/user-attachments/assets/30f1c91a-27aa-441e-9026-8d441855e7b9"
/>

This sucks! They look like they're wearing clown shoes for crying out
loud!


<img width="88" height="91" alt="image"
src="https://github.com/user-attachments/assets/0aa2febd-728b-4108-b64d-56173958cf27"
/>

This doesn't suck!

</details>

## Changelog

🆑 Robwo
fix: Teshari can now get properly bloody and bruised.
/🆑

---------

Co-authored-by: Alexis <catmc8565@gmail.com>
Co-authored-by: Waterpig <49160555+Maia-J@users.noreply.github.com>
This commit is contained in:
Robwo
2026-08-15 18:12:22 +02:00
committed by GitHub
co-authored by Alexis Waterpig
parent 4540212a1c
commit 1467508036
18 changed files with 115 additions and 29 deletions
+19 -1
View File
@@ -271,7 +271,7 @@
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
equipped_slot = ITEM_SLOT_FEET
var/static/mutable_appearance/bloody_feet
var/mutable_appearance/bloody_feet //BUBBER EDIT - ORIGINAL: var/static/mutable_appearance/bloody_feet
/// List of DNA on mob's feet, so we can handle it separately from blood on mob's hands
var/list/blood_DNA = null
@@ -282,17 +282,34 @@
wielder = parent
/*BUBBER EDIT BEGIN - Species specific blood icons.
if(!bloody_feet)
bloody_feet = mutable_appearance('icons/effects/blood.dmi', "shoeblood", SHOES_LAYER)
*/
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(on_clean))
RegisterSignal(parent, COMSIG_STEP_ON_BLOOD, PROC_REF(on_step_blood))
RegisterSignals(parent, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_MOB_UNEQUIPPED_ITEM), PROC_REF(shoecover))
// BUBBER ADDITION BEGIN - Species specific blood icons.
RegisterSignal(parent, COMSIG_SPECIES_GAIN, PROC_REF(on_species_change))
RegisterSignal(parent, COMSIG_SPECIES_LOSS, PROC_REF(on_species_change))
// BUBBER ADDITION END
if(new_blood)
blood_DNA = new_blood
update_icon()
// BUBBER EDIT ADDITION BEGIN - Species specific blood icons.
/datum/component/bloodysoles/feet/proc/on_species_change(datum/source)
SIGNAL_HANDLER
update_icon()
/datum/component/bloodysoles/feet/proc/get_blood_appearance()
if(icon_exists('modular_zubbers/icons/effects/blood_species.dmi', "shoeblood_[wielder.dna.species.id]"))
return mutable_appearance('modular_zubbers/icons/effects/blood_species.dmi', "shoeblood_[wielder.dna.species.id]", SHOES_LAYER)
return mutable_appearance('icons/effects/blood.dmi', "shoeblood", SHOES_LAYER)
// BUBBER EDIT ADDITION END
/datum/component/bloodysoles/feet/InheritComponent(datum/component/bloodysoles/feet/soles, original, list/new_blood)
if (!length(new_blood))
return
@@ -316,6 +333,7 @@
wielder.update_worn_shoes()
return
bloody_feet = get_blood_appearance() // BUBBER EDIT ADDITION
bloody_feet.color = wielder.get_blood_dna_color()
wielder.overlays_standing[SHOES_LAYER] = bloody_feet
wielder.apply_overlay(SHOES_LAYER)
+8 -1
View File
@@ -654,7 +654,14 @@ BLIND // can't see anything
if(clothing_flags & LARGE_WORN_ICON)
blood_overlay = mutable_appearance('icons/effects/64x64.dmi', "[blood_state]blood_large")
else
blood_overlay = mutable_appearance('icons/effects/blood.dmi', "[blood_state]blood")
//BUBBER EDIT BEGIN - Species specific blood icons.
// blood_overlay = mutable_appearance('icons/effects/blood.dmi', "[blood_state]blood") ORIGNAL
var/mob/living/carbon/human/wearer = loc
if(ishuman(wearer) && icon_exists('modular_zubbers/icons/effects/blood_species.dmi', "[blood_state]blood_[wearer.dna.species.id]"))
blood_overlay = mutable_appearance('modular_zubbers/icons/effects/blood_species.dmi', "[blood_state]blood_[wearer.dna.species.id]")
else
blood_overlay = mutable_appearance('icons/effects/blood.dmi', "[blood_state]blood")
//BUBBER EDIT END
blood_overlay.color = get_blood_dna_color()
+8 -1
View File
@@ -49,7 +49,14 @@
if(isinhands)
return
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
//BUBBER EDIT BEGIN - Species specific damage states.
//. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves") //ORIGINAL
var/mob/living/carbon/human/wearer = loc
if(ishuman(wearer) && icon_exists('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedgloves_[wearer.dna.species.id]"))
. += mutable_appearance('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedgloves_[wearer.dna.species.id]")
else
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
//BUBBER EDIT END
/obj/item/clothing/gloves/separate_worn_overlays(mutable_appearance/standing, mutable_appearance/draw_target, isinhands, icon_file, bodyshape = NONE)
. = ..()
+8 -1
View File
@@ -60,7 +60,14 @@
if(isinhands)
return
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
//BUBBER EDIT BEGIN - Species specific damage states.
//. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet") //ORIGINAL
var/mob/living/carbon/human/wearer = loc
if(ishuman(wearer) && icon_exists('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedhelmet_[wearer.dna.species.id]"))
. += mutable_appearance('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedhelmet_[wearer.dna.species.id]")
else
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
//BUBBER EDIT END
/obj/item/clothing/head/separate_worn_overlays(mutable_appearance/standing, mutable_appearance/draw_target, isinhands, icon_file, bodyshape = NONE)
. = ..()
+8 -1
View File
@@ -31,7 +31,14 @@
if(isinhands || !(body_parts_covered & HEAD))
return
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
//BUBBER EDIT BEGIN - Species specific damage states.
//. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask") //ORIGINAL
var/mob/living/carbon/human/wearer = loc
if(ishuman(wearer) && icon_exists('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedmask_[wearer.dna.species.id]"))
. += mutable_appearance('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedmask_[wearer.dna.species.id]")
else
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
//BUBBER EDIT END
/obj/item/clothing/mask/separate_worn_overlays(mutable_appearance/standing, mutable_appearance/draw_target, isinhands, icon_file, bodyshape = NONE)
. = ..()
+8 -1
View File
@@ -13,7 +13,14 @@
if(isinhands || !(body_parts_covered & HEAD))
return
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
//BUBBER EDIT BEGIN - Species specific damage states.
//. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask") //ORIGINAL
var/mob/living/carbon/human/wearer = loc
if(ishuman(wearer) && icon_exists('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedmask_[wearer.dna.species.id]"))
. += mutable_appearance('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedmask_[wearer.dna.species.id]")
else
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
//BUBBER EDIT END
/obj/item/clothing/neck/separate_worn_overlays(mutable_appearance/standing, mutable_appearance/draw_target, isinhands, icon_file, bodyshape = NONE)
. = ..()
+8 -1
View File
@@ -72,7 +72,14 @@
if(isinhands)
return
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe")
//BUBBER EDIT BEGIN - Species specific damage states.
//. += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe") //ORIGINAL
var/mob/living/carbon/human/wearer = loc
if(ishuman(wearer) && icon_exists('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedshoe_[wearer.dna.species.id]"))
. += mutable_appearance('modular_zubbers/icons/effects/item_damage_species.dmi', "damagedshoe_[wearer.dna.species.id]")
else
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe")
//BUBBER EDIT END
/obj/item/clothing/shoes/separate_worn_overlays(mutable_appearance/standing, mutable_appearance/draw_target, isinhands = FALSE, icon_file, bodyshape = NONE)
. = ..()
+13 -13
View File
@@ -23,20 +23,20 @@
if(isinhands)
return
if(damaged_clothes)
//SKYRAT EDIT CHANGE BEGIN
//. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]") //ORIGINAL
var/damagefile2use = (bodyshape & STYLE_TAUR_ALL) ? 'modular_skyrat/master_files/icons/mob/64x32_item_damage.dmi' : 'icons/effects/item_damage.dmi'
. += mutable_appearance(damagefile2use, "damaged[blood_overlay_type]")
//SKYRAT EDIT CHANGE END
if(GET_ATOM_BLOOD_DNA_LENGTH(src))
//SKYRAT EDIT CHANGE BEGIN
//. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood") //ORIGINAL
var/bloodfile2use = (bodyshape & STYLE_TAUR_ALL) ? 'modular_skyrat/master_files/icons/mob/64x32_blood.dmi' : 'icons/effects/blood.dmi'
. += mutable_appearance(bloodfile2use, "[blood_overlay_type]blood")
//SKYRAT EDIT CHANGE END
//BUBBER EDIT BEGIN - Species specific damage states.
var/mob/living/carbon/human/wearer = loc
if(damaged_clothes)
//. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]") //ORIGINAL
//todo: the taur icon doesn't exist anymore. Needs replacement.
var/icon/damage_icon_file = (bodyshape & STYLE_TAUR_ALL) ? 'modular_skyrat/master_files/icons/mob/64x32_item_damage.dmi' : 'icons/effects/item_damage.dmi'
var/damage_icon_state = "damaged[blood_overlay_type]"
if(ishuman(wearer) && icon_exists('modular_zubbers/icons/effects/item_damage_species.dmi', "damaged[blood_overlay_type]_[wearer.dna.species.id]"))
damage_icon_file = 'modular_zubbers/icons/effects/item_damage_species.dmi'
damage_icon_state = "damaged[blood_overlay_type]_[wearer.dna.species.id]"
. += mutable_appearance(damage_icon_file, damage_icon_state)
//BUBBER EDIT END
if(!ishuman(wearer) || !wearer.w_uniform)
return
var/obj/item/clothing/under/undershirt = wearer.w_uniform
+8 -1
View File
@@ -112,7 +112,14 @@
if(isinhands)
return
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
//BUBBER EDIT BEGIN
//. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform") //ORIGINAL
var/mob/living/carbon/human/wearer = loc
if(ishuman(wearer) && icon_exists('modular_zubbers/icons/effects/item_damage_species.dmi', "damageduniform_[wearer.dna.species.id]"))
. += mutable_appearance('modular_zubbers/icons/effects/item_damage_species.dmi', "damageduniform_[wearer.dna.species.id]")
else
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
//BUBBER EDIT END
. += get_accessory_overlays()
/obj/item/clothing/under/separate_worn_overlays(mutable_appearance/standing, mutable_appearance/draw_target, isinhands = FALSE, icon_file, bodyshape = NONE)
@@ -302,11 +302,11 @@
if(!iter_part.dmg_overlay_type)
continue
if(isnull(damage_overlay) && (iter_part.brutestate || iter_part.burnstate))
damage_overlay = mutable_appearance('icons/mob/effects/dam_mob.dmi', "blank", -DAMAGE_LAYER, appearance_flags = KEEP_TOGETHER)
damage_overlay = mutable_appearance('modular_zubbers/icons/mob/effects/dam_mob.dmi', "blank", -DAMAGE_LAYER, appearance_flags = KEEP_TOGETHER) //BUBBER EDIT: Extra species damage icons. Original: 'icons/mob/effects/dam_mob.dmi'
if(iter_part.brutestate)
var/mutable_appearance/blood_damage_overlay = mutable_appearance('icons/mob/effects/dam_mob.dmi', "[iter_part.dmg_overlay_type]_[iter_part.body_zone]_[iter_part.brutestate]0", appearance_flags = RESET_COLOR) //we're adding icon_states of the base image as overlays
var/mutable_appearance/blood_damage_overlay = mutable_appearance('modular_zubbers/icons/mob/effects/dam_mob.dmi', "[iter_part.dmg_overlay_type]_[iter_part.body_zone]_[iter_part.brutestate]0", appearance_flags = RESET_COLOR) //we're adding icon_states of the base image as overlays //BUBBER EDIT: Extra species damage icons. Original: 'icons/mob/effects/dam_mob.dmi'
blood_damage_overlay.color = get_bloodtype()?.get_damage_color(src)
var/mutable_appearance/brute_damage_overlay = mutable_appearance('icons/mob/effects/dam_mob.dmi', "[iter_part.dmg_overlay_type]_[iter_part.body_zone]_[iter_part.brutestate]0_overlay", appearance_flags = RESET_COLOR)
var/mutable_appearance/brute_damage_overlay = mutable_appearance('modular_zubbers/icons/mob/effects/dam_mob.dmi', "[iter_part.dmg_overlay_type]_[iter_part.body_zone]_[iter_part.brutestate]0_overlay", appearance_flags = RESET_COLOR) //BUBBER EDIT: Extra species damage icons. Original: 'icons/mob/effects/dam_mob.dmi'
blood_damage_overlay.overlays += brute_damage_overlay
damage_overlay.add_overlay(blood_damage_overlay)
if(iter_part.burnstate)
@@ -330,10 +330,23 @@
var/mutable_appearance/wound_overlay
for(var/obj/item/bodypart/iter_part as anything in get_bodyparts())
if(iter_part.bleed_overlay_icon)
/*BUBBER EDIT BEGIN - Species specific bleed overlay icons.
var/mutable_appearance/blood_overlay = mutable_appearance('icons/mob/effects/bleed_overlays.dmi', "blank", -WOUND_LAYER, appearance_flags = KEEP_TOGETHER)
blood_overlay.color = blood_type.get_wound_color(src)
wound_overlay ||= blood_overlay
wound_overlay.add_overlay(iter_part.bleed_overlay_icon)
*/
var/icon/bleed_overlay_icon_file = 'icons/mob/effects/bleed_overlays.dmi'
var/bleed_overlay_icon_state = iter_part.bleed_overlay_icon
if(ishuman(src) && icon_exists('modular_zubbers/icons/mob/effects/bleed_overlays_species.dmi', "[iter_part.bleed_overlay_icon]_[src.dna.species.id]"))
bleed_overlay_icon_file = 'modular_zubbers/icons/mob/effects/bleed_overlays_species.dmi'
bleed_overlay_icon_state = "[iter_part.bleed_overlay_icon]_[src.dna.species.id]"
var/mutable_appearance/blood_overlay = mutable_appearance(bleed_overlay_icon_file, "blank", -WOUND_LAYER, appearance_flags = KEEP_TOGETHER)
blood_overlay.color = blood_type.get_wound_color(src)
wound_overlay ||= blood_overlay
wound_overlay.add_overlay(mutable_appearance(bleed_overlay_icon_file, bleed_overlay_icon_state))
//BUBBER EDIT END
if(isnull(wound_overlay))
return
+3 -3
View File
@@ -1364,14 +1364,14 @@
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)
var/image/brute_blood_overlay = image('modular_zubbers/icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_[brutestate]0", -DAMAGE_LAYER, dir = SOUTH) //BUBBER EDIT: Extra species damage icons. Original: 'icons/mob/effects/dam_mob.dmi'
brute_blood_overlay.color = get_color_from_blood_list(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)
var/mutable_appearance/brute_damage_overlay = mutable_appearance('modular_zubbers/icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_[brutestate]0_overlay", -DAMAGE_LAYER, appearance_flags = RESET_COLOR) //BUBBER EDIT: Extra species damage icons. Original: 'icons/mob/effects/dam_mob.dmi'
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)
. += image('modular_zubbers/icons/mob/effects/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_0[burnstate]", -DAMAGE_LAYER, dir = SOUTH) //BUBBER EDIT: Extra species damage icons. Original: 'icons/mob/effects/dam_mob.dmi'
if(is_husked)
. += huskify_image(thing_to_husk = limb)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

@@ -8,6 +8,7 @@
icon_greyscale = BODYPART_ICON_TESHARI
bodyshape = parent_type::bodyshape | BODYSHAPE_CUSTOM
limb_id = SPECIES_TESHARI
dmg_overlay_type = SPECIES_TESHARI
brute_modifier = TESHARI_BRUTE_MODIFIER
burn_modifier = TESHARI_BURN_MODIFIER
head_flags = HEAD_EYESPRITES|HEAD_EYECOLOR|HEAD_EYEHOLES|HEAD_DEBRAIN|HEAD_HAIR
@@ -36,6 +37,7 @@
icon_greyscale = BODYPART_ICON_TESHARI
bodyshape = parent_type::bodyshape | BODYSHAPE_CUSTOM
limb_id = SPECIES_TESHARI
dmg_overlay_type = SPECIES_TESHARI
brute_modifier = TESHARI_BRUTE_MODIFIER
burn_modifier = TESHARI_BURN_MODIFIER
@@ -77,26 +79,27 @@
icon_greyscale = BODYPART_ICON_TESHARI
bodyshape = parent_type::bodyshape | BODYSHAPE_CUSTOM
limb_id = SPECIES_TESHARI
dmg_overlay_type = SPECIES_TESHARI
unarmed_damage_low = TESHARI_PUNCH_LOW
unarmed_damage_high = TESHARI_PUNCH_HIGH
brute_modifier = TESHARI_BRUTE_MODIFIER
burn_modifier = TESHARI_BURN_MODIFIER
/obj/item/bodypart/arm/right/mutant/teshari
icon_greyscale = BODYPART_ICON_TESHARI
bodyshape = parent_type::bodyshape | BODYSHAPE_CUSTOM
limb_id = SPECIES_TESHARI
dmg_overlay_type = SPECIES_TESHARI
unarmed_damage_low = TESHARI_PUNCH_LOW
unarmed_damage_high = TESHARI_PUNCH_HIGH
brute_modifier = TESHARI_BRUTE_MODIFIER
burn_modifier = TESHARI_BURN_MODIFIER
/obj/item/bodypart/leg/left/mutant/teshari
icon_greyscale = BODYPART_ICON_TESHARI
bodyshape = parent_type::bodyshape | BODYSHAPE_CUSTOM
limb_id = SPECIES_TESHARI
dmg_overlay_type = SPECIES_TESHARI
digitigrade_type = /obj/item/bodypart/leg/left/digitigrade/teshari
brute_modifier = TESHARI_BRUTE_MODIFIER
burn_modifier = TESHARI_BURN_MODIFIER
@@ -105,6 +108,7 @@
icon_greyscale = BODYPART_ICON_TESHARI
bodyshape = parent_type::bodyshape | BODYSHAPE_CUSTOM
limb_id = SPECIES_TESHARI
dmg_overlay_type = SPECIES_TESHARI
digitigrade_type = /obj/item/bodypart/leg/right/digitigrade/teshari
brute_modifier = TESHARI_BRUTE_MODIFIER
burn_modifier = TESHARI_BURN_MODIFIER
@@ -113,6 +117,7 @@
icon_greyscale = BODYPART_ICON_TESHARI
bodyshape = parent_type::bodyshape | BODYSHAPE_CUSTOM
base_limb_id = SPECIES_TESHARI
dmg_overlay_type = SPECIES_TESHARI
brute_modifier = TESHARI_BRUTE_MODIFIER
burn_modifier = TESHARI_BURN_MODIFIER
@@ -120,6 +125,7 @@
icon_greyscale = BODYPART_ICON_TESHARI
bodyshape = parent_type::bodyshape | BODYSHAPE_CUSTOM
base_limb_id = SPECIES_TESHARI
dmg_overlay_type = SPECIES_TESHARI
brute_modifier = TESHARI_BRUTE_MODIFIER
burn_modifier = TESHARI_BURN_MODIFIER
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB