Skip to content

Commit

Permalink
[MIRROR] blood overlay handling rework
Browse files Browse the repository at this point in the history
  • Loading branch information
CakeQ authored and LordNest committed Feb 21, 2025
1 parent 11d0c4f commit a6d59f2
Show file tree
Hide file tree
Showing 16 changed files with 196 additions and 103 deletions.
56 changes: 49 additions & 7 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
var/was_bloodied = FALSE
/// Color. The color of the blood overlay effect, if present.
var/blood_color
/// The amount of times blood will transfer to other atoms.
var/blood_transfer_amount = 0
/// Integer. The `world.time` the atom was last bumped into. Only used by some subtypes to prevent bump spamming.
var/last_bumped = 0
/// Bitflag (Any of `PASS_FLAG_*`). Flags indicating the types of dense objects this atom is able to pass through/over.
Expand Down Expand Up @@ -609,23 +611,63 @@
* Returns boolean - `TRUE` if the atom was bloodied, `FALSE` otherwise.
*/
/atom/proc/add_blood(mob/living/carbon/human/M as mob)
if(!istype(M))
return 0
if (!istype(M.dna, /datum/dna))
M.dna = new /datum/dna(null)
M.dna.real_name = M.real_name
M.check_dna()
return add_blood_custom(M.species.get_blood_colour(M), 3, list(M.dna))

/**
* Adds custom blood effects and DNA to the atom.
*
* **Parameters**:
* - `colour` - The blood colour to apply.
* - `colour` - The blood colour to apply.
* - `colour` - The blood colour to apply.
*
* Returns boolean - `TRUE` if the atom was bloodied, `FALSE` otherwise.
*/
/atom/proc/add_blood_custom(source_blood_color = COLOR_BLOOD_HUMAN, amount = 1, list/source_blood_DNA = list())
if(atom_flags & ATOM_FLAG_NO_BLOOD)
return 0

if(!blood_DNA || !istype(blood_DNA, /list)) //if our list of DNA doesn't exist yet (or isn't a list) initialise it.
blood_DNA = list()

was_bloodied = 1
blood_color = COLOR_BLOOD_HUMAN
if(istype(M))
if (!istype(M.dna, /datum/dna))
M.dna = new /datum/dna(null)
M.dna.real_name = M.real_name
M.check_dna()
blood_color = M.species.get_blood_colour(M)
blood_color = source_blood_color
blood_DNA |= source_blood_DNA.Copy()
blood_transfer_amount = max(amount, blood_transfer_amount)
. = 1
return 1

/**
* Transfers existing blood effects to the target.
*
* **Parameters**:
* - `target` - The target mob to transfer to.
* - `target_zone` - Optional target zone for humanoid mobs to apply to a specific part of the body.
*
* Returns boolean - `TRUE` if the atom was bloodied, `FALSE` otherwise.
*/
/atom/proc/transfer_blood(mob/living/carbon/human/target, target_zone)
if (!ishuman(target))
return 0
var/obj/item/clothing/equipped_item = target.get_covering_equipped_item_by_zone(target_zone)
var/taken = rand(1,blood_transfer_amount)
blood_transfer_amount -= taken
if(istype(equipped_item))
equipped_item.add_blood_custom(blood_color, taken, blood_DNA)
else
switch(target_zone)
if(BP_L_HAND , BP_R_HAND)
target.bloody_hands_custom(blood_color, 3, blood_DNA)
if(BP_CHEST, BP_GROIN, BP_L_ARM , BP_R_ARM, BP_L_LEG , BP_R_LEG)
target.bloody_body_custom(blood_color, taken, blood_DNA)
return 1

/mob/living/proc/handle_additional_vomit_reagents(obj/decal/cleanable/vomit/vomit)
vomit.reagents.add_reagent(/datum/reagent/acid/stomach, 5)

Expand Down
53 changes: 14 additions & 39 deletions code/game/objects/effects/decals/Cleanable/humans.dm
Original file line number Diff line number Diff line change
Expand Up @@ -104,39 +104,10 @@ var/global/list/image/splatter_cache=list()
if(MOVING_DELIBERATELY(perp))
return

var/obj/item/organ/external/l_foot = perp.get_organ(BP_L_FOOT)
var/obj/item/organ/external/r_foot = perp.get_organ(BP_R_FOOT)
var/hasfeet = 1
if((!l_foot || l_foot.is_stump()) && (!r_foot || r_foot.is_stump()))
hasfeet = 0
if(perp.shoes && !perp.buckled)//Adding blood to shoes
var/obj/item/clothing/shoes/S = perp.shoes
if(istype(S))
S.blood_color = basecolor
S.track_blood = max(amount,S.track_blood)
if(!S.blood_overlay)
S.generate_blood_overlay()
if(!S.blood_DNA)
S.blood_DNA = list()
S.blood_overlay.color = basecolor
S.AddOverlays(S.blood_overlay)
if(S.blood_overlay && S.blood_overlay.color != basecolor)
S.blood_overlay.color = basecolor
S.ClearOverlays()
S.AddOverlays(S.blood_overlay)
S.blood_DNA |= blood_DNA.Copy()

else if (hasfeet)//Or feet
perp.feet_blood_color = basecolor
perp.track_blood = max(amount, perp.track_blood)
if(!perp.feet_blood_DNA)
perp.feet_blood_DNA = list()
perp.feet_blood_DNA |= blood_DNA.Copy()
else if (perp.buckled && istype(perp.buckled, /obj/structure/bed/chair/wheelchair))
if (!perp.bloody_feet_custom(basecolor, amount, blood_DNA) && perp.buckled && istype(perp.buckled, /obj/structure/bed/chair/wheelchair))
var/obj/structure/bed/chair/wheelchair/W = perp.buckled
W.bloodiness = 4

perp.update_inv_shoes(1)
W.add_blood_custom(basecolor, amount, blood_DNA)
amount--

/obj/decal/cleanable/blood/proc/dry()
Expand All @@ -154,14 +125,18 @@ var/global/list/image/splatter_cache=list()
return
var/taken = rand(1,amount)
amount -= taken
to_chat(user, SPAN_NOTICE("You get some of \the [src] on your hands."))
if (!user.blood_DNA)
user.blood_DNA = list()
user.blood_DNA |= blood_DNA.Copy()
user.bloody_hands = taken
user.hand_blood_color = basecolor
user.update_inv_gloves(1)
user.verbs += /mob/living/carbon/human/proc/bloody_doodle
var/obj/item/clothing/gloves/gloves = user.get_equipped_item(slot_gloves)
if(istype(gloves))
gloves.add_blood_custom(basecolor, taken, list(blood_DNA.Copy()))
else
to_chat(user, SPAN_NOTICE("You get some of \the [src] on your hands."))
if (!user.blood_DNA)
user.blood_DNA = list()
user.blood_DNA |= blood_DNA.Copy()
user.bloody_hands = taken
user.hand_blood_color = basecolor
user.update_inv_gloves(1)
user.verbs += /mob/living/carbon/human/proc/bloody_doodle

/obj/decal/cleanable/blood/splatter
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
Expand Down
29 changes: 21 additions & 8 deletions code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@
if(!temp)
to_chat(user, SPAN_NOTICE("You try to use your hand, but realize it is no longer attached!"))
return TRUE
var/obj/item/clothing/gloves/gloves = user.get_equipped_item(slot_gloves)
if(istype(gloves) && gloves.blood_transfer_amount >= 1)
var/taken = rand(1, gloves.blood_transfer_amount)
gloves.blood_transfer_amount -= taken
add_blood_custom(gloves.blood_color, taken, gloves.blood_DNA)
else if(H.bloody_hands >= 1)
var/taken = rand(1, H.bloody_hands)
H.bloody_hands -= taken
add_blood_custom(H.hand_blood_color, taken, H.hands_blood_DNA)

var/old_loc = loc

Expand Down Expand Up @@ -672,7 +681,7 @@ var/global/list/slot_flags_enumeration = list(
CutOverlays(blood_overlay)
if(istype(src, /obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = src
G.transfer_blood = 0
G.blood_transfer_amount = 0
trace_DNA = null

/obj/item/reveal_blood()
Expand All @@ -682,7 +691,7 @@ var/global/list/slot_flags_enumeration = list(
blood_overlay.color = COLOR_LUMINOL
update_icon()

/obj/item/add_blood(mob/living/carbon/human/M as mob)
/obj/item/add_blood_custom(source_blood_color = COLOR_BLOOD_HUMAN, amount = 3, list/source_blood_DNA = list())
if (!..())
return 0

Expand All @@ -694,16 +703,20 @@ var/global/list/slot_flags_enumeration = list(
generate_blood_overlay()

//apply the blood-splatter overlay if it isn't already in there
if(!length(blood_DNA))
if(blood_overlay.color != blood_color)
blood_overlay.color = blood_color
AddOverlays(blood_overlay)

blood_transfer_amount = max(amount, blood_transfer_amount)

//if this blood isn't already in the list, add it
if(istype(M))
if(blood_DNA[M.dna.unique_enzymes])
return 0 //already bloodied with this blood. Cannot add more.
blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
return 1 //we applied blood to the item
var/added_blood = 0
for(var/datum/dna/dna in source_blood_DNA)
if(blood_DNA[dna.unique_enzymes])
continue //already bloodied with this blood. Cannot add more.
blood_DNA[dna.unique_enzymes] = dna.b_type
added_blood = 1
return added_blood

GLOBAL_LIST_EMPTY(blood_overlay_cache)
#define BLOOD_OVERLAY_CACHE_INDEX "[icon]" + icon_state + blood_color
Expand Down
4 changes: 2 additions & 2 deletions code/game/turfs/simulated.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@
var/obj/item/clothing/shoes/S = H.shoes
if(istype(S))
S.handle_movement(src, MOVING_QUICKLY(H))
if(S.track_blood && S.blood_DNA)
if(S.blood_transfer_amount && S.blood_DNA)
bloodDNA = S.blood_DNA
bloodcolor = S.blood_color
S.track_blood--
S.blood_transfer_amount--
else
if(H.track_blood && H.feet_blood_DNA)
bloodDNA = H.feet_blood_DNA
Expand Down
2 changes: 1 addition & 1 deletion code/modules/clothing/_clothing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ BLIND // can't see anything
)
slot_flags = SLOT_OCLOTHING
item_flags = ITEM_FLAG_WASHER_ALLOWED
blood_overlay_type = "suit"
blood_overlay_type = "suitblood"
siemens_coefficient = 0.9
w_class = ITEM_SIZE_NORMAL

Expand Down
12 changes: 6 additions & 6 deletions code/modules/clothing/suits/armor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
name = "armor"
desc = "An armored vest that protects against some damage."
icon_state = "armor"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
body_parts_covered = UPPER_TORSO|LOWER_TORSO
cold_protection = UPPER_TORSO|LOWER_TORSO
heat_protection = UPPER_TORSO|LOWER_TORSO
Expand Down Expand Up @@ -69,7 +69,7 @@
desc = "An armored jacket used in special operations."
icon_state = "detective"
item_state = "detective"
blood_overlay_type = "coat"
blood_overlay_type = "coatblood"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
heat_protection = UPPER_TORSO|LOWER_TORSO|ARMS
Expand All @@ -80,7 +80,7 @@
name = "armor"
desc = "An armored vest with a detective's badge on it."
icon_state = "detective-armor"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
body_parts_covered = UPPER_TORSO|LOWER_TORSO
armor = list(
melee = ARMOR_MELEE_RESISTANT,
Expand All @@ -98,7 +98,7 @@
desc = "Someone separated our Chief Science Officer from their own head!"
active = 0.0
icon_state = "reactiveoff"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
armor = null


Expand Down Expand Up @@ -283,7 +283,7 @@
name = "makeshift armor"
desc = "A pair of sheets held together by rods and wires, meant to cover your upper body and back."
icon_state = "makeshift-armor"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
armor = list(
melee = ARMOR_MELEE_KNIVES,
bullet = ARMOR_BALLISTIC_SMALL,
Expand All @@ -303,7 +303,7 @@
icon_state = "pcarrier"
valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA, ACCESSORY_SLOT_ARMOR_CHEST, ACCESSORY_SLOT_ARMOR_ARMS, ACCESSORY_SLOT_ARMOR_LEGS, ACCESSORY_SLOT_ARMOR_STORAGE, ACCESSORY_SLOT_ARMOR_MISC)
restricted_accessory_slots = list(ACCESSORY_SLOT_ARMOR_CHEST, ACCESSORY_SLOT_ARMOR_ARMS, ACCESSORY_SLOT_ARMOR_LEGS, ACCESSORY_SLOT_ARMOR_STORAGE)
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
flags_inv = 0

sprite_sheets = list(
Expand Down
24 changes: 12 additions & 12 deletions code/modules/clothing/suits/jobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
desc = "A basic blue apron."
icon_state = "apron"
item_state = "apron"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
body_parts_covered = 0
species_restricted = null
allowed = list (/obj/item/reagent_containers/spray/plantbgone,/obj/item/device/scanner/plant,/obj/item/seeds,/obj/item/reagent_containers/glass/bottle,/obj/item/material/minihoe)
Expand Down Expand Up @@ -82,7 +82,7 @@
desc = "A basic, dull, white chef's apron."
icon_state = "apronchef"
species_restricted = null
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
body_parts_covered = 0

//Security
Expand Down Expand Up @@ -110,7 +110,7 @@
desc = "A rugged canvas trenchcoat, designed and created by TX Fabrication Corp. The coat is externally impact resistant - perfect for your next act of autodefenestration!"
icon_state = "detective"
valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA)
blood_overlay_type = "coat"
blood_overlay_type = "coatblood"
body_parts_covered = UPPER_TORSO|ARMS
allowed = list(
/obj/item/tank/oxygen_emergency,
Expand Down Expand Up @@ -182,7 +182,7 @@
name = "hazard vest"
desc = "A high-visibility vest used in work zones."
icon_state = "hazard"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
species_restricted = null
allowed = list (
/obj/item/device/scanner/gas,
Expand Down Expand Up @@ -245,7 +245,7 @@
name = "high visibility jacket"
desc = "A loose-fitting, high visibility jacket to help crew be recognizable in high traffic areas with large industrial equipment. Don't catch the Charon's landing gear with your teeth!"
icon_state = "highvis"
blood_overlay_type = "coat"
blood_overlay_type = "coatblood"
body_parts_covered = UPPER_TORSO|ARMS
valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA)

Expand All @@ -254,15 +254,15 @@
name = "suit jacket"
desc = "A snappy dress jacket."
icon_state = "suitjacket"
blood_overlay_type = "coat"
blood_overlay_type = "coatblood"
body_parts_covered = UPPER_TORSO|ARMS
valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA)

/obj/item/clothing/suit/storage/toggle/suit_double
name = "double-breasted suit jacket"
desc = "A snappy, double-breasted dress jacket."
icon_state = "suitjacket_double"
blood_overlay_type = "coat"
blood_overlay_type = "coatblood"
body_parts_covered = UPPER_TORSO|ARMS
valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA)

Expand All @@ -283,7 +283,7 @@
name = "first responder jacket"
desc = "A high-visibility jacket worn by medical first responders."
icon_state = "fr_jacket"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
allowed = list(
/obj/item/stack/medical,
/obj/item/reagent_containers/dropper,
Expand Down Expand Up @@ -314,7 +314,7 @@
name = "chest-rig"
desc = "A grey chest-rig with black pouches. For when you wish you had more hands."
icon_state = "chest-rig"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
allowed = list(
/obj/item/device/flashlight,
/obj/item/tank/oxygen_emergency,
Expand All @@ -336,7 +336,7 @@
name = "hazard chest-rig"
desc = "A grey chest-rig with black pouches and orange markings worn by engineers. It has an 'Engineer' tag on its chest."
icon_state = "engi-chest-rig"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
allowed = list (
/obj/item/device/flashlight,
/obj/item/tank/oxygen_emergency,
Expand All @@ -361,7 +361,7 @@
name = "\improper MT chest-rig"
desc = "A white chest-rig with black pouches worn by medical first responders. It has a 'Medic' tag on its chest."
icon_state = "med-chest-rig"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
allowed = list(
/obj/item/device/flashlight,
/obj/item/tank/oxygen_emergency,
Expand All @@ -384,7 +384,7 @@
name = "surgical apron"
desc = "A sterile blue apron for performing surgery."
icon_state = "surgical"
blood_overlay_type = "armor"
blood_overlay_type = "armorblood"
body_parts_covered = UPPER_TORSO|LOWER_TORSO
allowed = list(
/obj/item/stack/medical,
Expand Down
Loading

0 comments on commit a6d59f2

Please sign in to comment.