Skip to content

Commit

Permalink
Fix organs having no DNA and become bloody when violently removed (tg…
Browse files Browse the repository at this point in the history
…station#78519)

## About The Pull Request
Fixes tgstation#75585

Organs now spawn with DNA that can be scanned by a forensic scanner.
Robotic organs have no DNA and organic organs with no prior owner spawn
with synthetic DNA. If the syntenic DNA organ is inserted into someone,
the organ inherits the owners DNA. This override can only happen once
and only if the organ has never been used.

Any organ removed is covered in blood, unless it's surgically removed. I
had to give the `NO_BLOOD_ON_ITEM` to hearts since the icon was
glitching out with blood decals on it. It also appears that moth wings
(and maybe normal ones?) do not inherit blood decals naturally despite
being covered in blood. No idea why, but that's out of scope for this
PR.

## Why It's Good For The Game
Forensics scanning is now more robust. 

## Changelog
:cl:
fix: Fix organs having no DNA and become bloody when violently removed. 
/:cl:

---------

Co-authored-by: Jacquerel <[email protected]>
  • Loading branch information
timothymtorres and Jacquerel authored Oct 2, 2023
1 parent 0070b8d commit d4d5e82
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 2 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/surgery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#define ORGAN_UNREMOVABLE (1<<8)
/// Can't be seen by scanners, doesn't anger body purists
#define ORGAN_HIDDEN (1<<9)
/// Has the organ already been inserted inside someone
#define ORGAN_VIRGIN (1<<10)

/// Helper to figure out if a limb is organic
#define IS_ORGANIC_LIMB(limb) (limb.bodytype & BODYTYPE_ORGANIC)
Expand Down
2 changes: 2 additions & 0 deletions code/modules/forensics/_forensics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@
/datum/forensics/proc/check_blood()
if(!parent || !isitem(parent.resolve()))
return
if(isorgan(parent.resolve())) // organs don't spawn with blood decals by default
return
if(!length(blood_DNA))
return
var/atom/parent_atom = parent.resolve()
Expand Down
26 changes: 25 additions & 1 deletion code/modules/surgery/organs/_organ.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
throwforce = 0
/// The mob that owns this organ.
var/mob/living/carbon/owner = null
/// The cached info about the blood this organ belongs to
var/list/blood_dna_info = list("Synthetic DNA" = "O+") // not every organ spawns inside a person
/// The body zone this organ is supposed to inhabit.
var/zone = BODY_ZONE_CHEST
/**
Expand All @@ -14,7 +16,7 @@
*/
var/slot
/// Random flags that describe this organ
var/organ_flags = ORGAN_ORGANIC | ORGAN_EDIBLE
var/organ_flags = ORGAN_ORGANIC | ORGAN_EDIBLE | ORGAN_VIRGIN
/// Maximum damage the organ can take, ever.
var/maxHealth = STANDARD_ORGAN_THRESHOLD
/**
Expand Down Expand Up @@ -75,6 +77,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
volume = reagent_vol,\
after_eat = CALLBACK(src, PROC_REF(OnEatFrom)))

if(!IS_ROBOTIC_ORGAN(src))
add_blood_DNA(blood_dna_info)

/*
* Insert the organ into the select mob.
*
Expand All @@ -100,6 +105,14 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
receiver.organs_slot[slot] = src
owner = receiver

if(!IS_ROBOTIC_ORGAN(src) && (organ_flags & ORGAN_VIRGIN))
blood_dna_info = receiver.get_blood_dna_list()
// need to remove the synethic blood DNA that is initialized
// wash also adds the blood dna again
wash(CLEAN_TYPE_BLOOD)
organ_flags &= ~ORGAN_VIRGIN


// Apply unique side-effects. Return value does not matter.
on_insert(receiver, special)

Expand Down Expand Up @@ -168,6 +181,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner)
SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special)

if(!IS_ROBOTIC_ORGAN(src) && !(item_flags & NO_BLOOD_ON_ITEM) && !QDELING(src))
AddElement(/datum/element/decal/blood)

var/list/diseases = organ_owner.get_static_viruses()
if(!LAZYLEN(diseases))
return
Expand Down Expand Up @@ -228,6 +244,14 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
/obj/item/organ/proc/on_surgical_removal(mob/living/user, mob/living/carbon/old_owner, target_zone, obj/item/tool)
SHOULD_CALL_PARENT(TRUE)
SEND_SIGNAL(src, COMSIG_ORGAN_SURGICALLY_REMOVED, user, old_owner, target_zone, tool)
RemoveElement(/datum/element/decal/blood)

/obj/item/organ/wash(clean_types)
. = ..()

// always add the original dna to the organ after it's washed
if(!IS_ROBOTIC_ORGAN(src) && (clean_types & CLEAN_TYPE_BLOOD))
add_blood_DNA(blood_dna_info)

/obj/item/organ/process(seconds_per_tick, times_fired)
return
Expand Down
2 changes: 1 addition & 1 deletion code/modules/surgery/organs/internal/heart/_heart.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
visual = FALSE
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_HEART

item_flags = NO_BLOOD_ON_ITEM
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = 2.5 * STANDARD_ORGAN_DECAY //designed to fail around 6 minutes after death

Expand Down

0 comments on commit d4d5e82

Please sign in to comment.