Fix organs having no DNA and become bloody when violently removed (#78519)

## About The Pull Request
Fixes #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
🆑
fix: Fix organs having no DNA and become bloody when violently removed. 
/🆑

---------

Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
Tim
2023-10-02 17:29:56 +01:00
committed by GitHub
co-authored by Jacquerel
parent 0070b8df17
commit d4d5e8251c
4 changed files with 30 additions and 2 deletions
+2
View File
@@ -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)
+2
View File
@@ -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()
+25 -1
View File
@@ -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
/**
@@ -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
/**
@@ -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.
*
@@ -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)
@@ -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
@@ -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
@@ -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