Skip to content

Commit

Permalink
Revives Organ Datumization (ParadiseSS13#23397)
Browse files Browse the repository at this point in the history
* first runthrough lol

* okay make this shit actually work

* nerfs slime people

* fixes

* more changes

* fix

* bim bim bam bam

* ok back in the head becuz i dont give a shit

* Sirryan review

* Sirryan review

* Fixes CI

* Stealthy CI fail

---------

Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com>
  • Loading branch information
DGamerL and Contrabang authored Jan 21, 2024
1 parent 0b8c196 commit 79a7558
Show file tree
Hide file tree
Showing 32 changed files with 653 additions and 521 deletions.
4 changes: 4 additions & 0 deletions code/__DEFINES/mob_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#define ORGAN_BURNT (1 << 7)
#define ORGAN_SALVED (1 << 8)

// Organ datum defines. Each one of these represents a slot for organ datums in internal_organ_datums
#define ORGAN_DATUM_HEART "heart"
#define ORGAN_DATUM_LUNGS "lungs"

// For limb resistance flags
#define CANNOT_BREAK (1 << 0)
#define CANNOT_DISMEMBER (1 << 1)
Expand Down
10 changes: 5 additions & 5 deletions code/datums/components/defibrillator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,12 @@
return

if(target.undergoing_cardiac_arrest()) // Can have a heart attack and heart is either missing, necrotic, or not beating
var/obj/item/organ/internal/heart/heart = target.get_int_organ(/obj/item/organ/internal/heart)
var/datum/organ/heart/heart = target.get_int_organ_datum(ORGAN_DATUM_HEART)
if(!heart)
user.visible_message("<span class='boldnotice'>[defib_ref] buzzes: Resuscitation failed - Failed to pick up any heart electrical activity.</span>")
else if(heart.status & ORGAN_DEAD)
else if(heart.linked_organ.status & ORGAN_DEAD)
user.visible_message("<span class='boldnotice'>[defib_ref] buzzes: Resuscitation failed - Heart necrosis detected.</span>")
if(!heart || (heart.status & ORGAN_DEAD))
if(!heart || (heart.linked_organ.status & ORGAN_DEAD))
playsound(get_turf(defib_ref), 'sound/machines/defib_failed.ogg', 50, 0)
busy = FALSE
return
Expand Down Expand Up @@ -384,8 +384,8 @@
return

if(electrocute_mob(affecting, power_source, origin)) // shock anyone touching them >:)
var/obj/item/organ/internal/heart/HE = affecting.get_organ_slot("heart")
if(HE.parent_organ == "chest" && affecting.has_both_hands()) // making sure the shock will go through their heart (drask hearts are in their head), and that they have both arms so the shock can cross their heart inside their chest
var/datum/organ/heart/heart = affecting.get_int_organ_datum(ORGAN_DATUM_HEART)
if(heart.linked_organ.parent_organ == "chest" && affecting.has_both_hands()) // making sure the shock will go through their heart (drask hearts are in their head), and that they have both arms so the shock can cross their heart inside their chest
affecting.visible_message("<span class='danger'>[affecting]'s entire body shakes as a shock travels up [affecting.p_their()] arm!</span>", \
"<span class='userdanger'>You feel a powerful shock travel up your [affecting.hand ? affecting.get_organ("l_arm") : affecting.get_organ("r_arm")] and back down your [affecting.hand ? affecting.get_organ("r_arm") : affecting.get_organ("l_arm")]!</span>")
affecting.set_heartattack(TRUE)
Expand Down
11 changes: 8 additions & 3 deletions code/datums/diseases/_MobProcs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,14 @@
if(HAS_TRAIT(src, TRAIT_VIRUSIMMUNE) && !D.bypasses_immunity)
return FALSE

for(var/thing in D.required_organs)
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
return FALSE
for(var/organ in D.required_organs)
if(istext(organ) && get_int_organ_datum(organ))
continue
if(locate(organ) in internal_organs)
continue
if(locate(organ) in bodyparts)
continue
return FALSE
return ..()

/mob/living/carbon/human/monkey/CanContractDisease(datum/disease/D)
Expand Down
5 changes: 4 additions & 1 deletion code/datums/diseases/critical.dm
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@
cure_chance = 10
stage_prob = 5
severity = HARMFUL
required_organs = list(/obj/item/organ/internal/heart)
disease_flags = CURABLE
required_organs = list(ORGAN_DATUM_HEART)
bypasses_immunity = TRUE
virus_heal_resistant = TRUE

/datum/disease/critical/heart_failure/stage_act()
if(..())
Expand Down
4 changes: 2 additions & 2 deletions code/datums/diseases/tuberculosis.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
viable_mobtypes = list(/mob/living/carbon/human)
cure_chance = 5 // Like hell are you getting out of hell
desc = "A rare highly transmittable virulent virus. Few samples exist, rumoured to be carefully grown and cultured by clandestine bio-weapon specialists. Causes fever, blood vomiting, lung damage, weight loss, and fatigue."
required_organs = list(/obj/item/organ/internal/lungs)
required_organs = list(ORGAN_DATUM_LUNGS)
severity = HARMFUL
bypasses_immunity = TRUE // Fungal and bacterial in nature; also infects the lungs
bypasses_immunity = TRUE //Fungal and bacterial in nature; also infects the lungs

/datum/disease/tuberculosis/stage_act()
if(!..())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

/datum/surgery_step/internal/extract_organ/begin_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
for(var/obj/item/I in target.internal_organs)
// Allows for multiple subtypes of heart.
// Allows for multiple subtypes of heart. Doesn't use the organ datum so that slimes dont get their brains pulled out of their head
if(istype(I, /obj/item/organ/internal/heart))
IC = I
break
Expand Down
8 changes: 3 additions & 5 deletions code/game/gamemodes/miniantags/abduction/gland.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
dead_icon = null
status = ORGAN_ROBOT
origin_tech = "materials=4;biotech=7;abductor=3"
beating = TRUE
organ_datums = list(/datum/organ/heart/always_beating) // alien glands are immune to stopping
tough = TRUE //not easily broken by combat damage

var/cooldown_low = 300
var/cooldown_high = 300
var/next_activation = 0
var/uses // -1 For inifinite
var/human_only = FALSE
var/active = FALSE
tough = TRUE //not easily broken by combat damage

var/mind_control_uses = 1
var/mind_control_duration = 1800
Expand Down Expand Up @@ -84,9 +85,6 @@
update_gland_hud()

/obj/item/organ/internal/heart/gland/on_life()
if(!beating)
// alien glands are immune to stopping.
beating = TRUE
if(!active)
return
if(!ownerCheck())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,14 @@
icon = 'icons/obj/surgery.dmi'
icon_state = "demon_heart"
origin_tech = "combat=5;biotech=7"
organ_datums = list(/datum/organ/heart/always_beating)

/obj/item/organ/internal/heart/demon/update_icon_state()
return //always beating visually

/obj/item/organ/internal/heart/demon/prepare_eat()
return // Just so people don't accidentally waste it

/obj/item/organ/internal/heart/demon/Stop()
return 0 // Always beating.

/obj/item/organ/internal/heart/demon/attack_self(mob/living/user)
user.visible_message("<span class='warning'>[user] raises [src] to [user.p_their()] mouth and tears into it with [user.p_their()] teeth!</span>", \
"<span class='danger'>An unnatural hunger consumes you. You raise [src] to your mouth and devour it!</span>")
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/devices/painter/painter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
/obj/item/painter/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is inhaling toner from [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(src, usesound, 50, TRUE)
var/obj/item/organ/internal/lungs/L = user.get_organ_slot("lungs")
var/obj/item/organ/internal/lungs/L = user.get_organ_slot("lungs") // not going to use an organ datum here, would be too easy for slime people to throw up their brains
var/turf/T = get_turf(user)
if(!do_mob(user, user, 3 SECONDS) || !L)
return SHAME
Expand Down
6 changes: 3 additions & 3 deletions code/game/objects/items/devices/scanners.dm
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,11 @@ REAGENT SCANNER
if(H.undergoing_cardiac_arrest())
var/obj/item/organ/internal/heart/heart = H.get_int_organ(/obj/item/organ/internal/heart)
if(heart && !(heart.status & ORGAN_DEAD))
msgs += "<span class='notice'><font color='red'><b>The patient's heart has stopped.</b>\nPossible Cure: Electric Shock</font></span>"
msgs += "<span class='notice'><font color='red'><b>The patient's heart has stopped.</b>\nPossible Cure: Electric Shock</font>"
else if(heart && (heart.status & ORGAN_DEAD))
msgs += "<span class='notice'><font color='red'><b>Subject's heart is necrotic.</b></font></span>"
msgs += "<span class='notice'><font color='red'><b>Subject's heart is necrotic.</b></font>"
else if(!heart)
msgs += "<span class='notice'><font color='red'><b>Subject has no heart.</b></font></span>"
msgs += "<span class='notice'><font color='red'><b>Subject has no heart.</b></font>"

if(H.getStaminaLoss())
msgs += "<span class='info'>Subject appears to be suffering from fatigue.</span>"
Expand Down
6 changes: 4 additions & 2 deletions code/modules/clothing/under/accessories/accessory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,10 @@
user.visible_message("[user] places [src] against [user.p_their()] chest and listens attentively.", "You place [src] against your chest...")
else
user.visible_message("[user] places \the [src] against [M]'s chest and listens attentively.", "You place \the [src] against [M]'s chest...")
var/obj/item/organ/internal/H = M.get_int_organ(/obj/item/organ/internal/heart)
var/obj/item/organ/internal/L = M.get_int_organ(/obj/item/organ/internal/lungs)
var/datum/organ/heart/heart_datum = M.get_int_organ_datum(ORGAN_DATUM_HEART)
var/obj/item/organ/internal/H = heart_datum.linked_organ
var/datum/organ/lungs/lung_datum = M.get_int_organ_datum(ORGAN_DATUM_LUNGS)
var/obj/item/organ/internal/L = lung_datum.linked_organ
if(M.pulse && (H || (L && !HAS_TRAIT(M, TRAIT_NOBREATH))))
var/color = "notice"
if(H)
Expand Down
6 changes: 4 additions & 2 deletions code/modules/mob/living/carbon/carbon_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
pressure_resistance = 15
var/list/stomach_contents
var/list/processing_patches
var/list/internal_organs = list()
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
var/list/internal_organs = list()
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
/// An associated list of strings that associate it with the organ datum, e.g. [ORGAN_DATUM_HEART] = /datum/organ/heart
var/list/internal_organ_datums = list()

var/life_tick = 0 // The amount of life ticks that have processed on this mob.

Expand Down
5 changes: 4 additions & 1 deletion code/modules/mob/living/carbon/carbon_life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
if(status_flags & GODMODE)
return FALSE

var/lungs = get_organ_slot("lungs")
var/lungs = get_int_organ_datum(ORGAN_DATUM_LUNGS)
if(!lungs)
adjustOxyLoss(2)

Expand Down Expand Up @@ -201,6 +201,9 @@
for(var/thing in internal_organs)
var/obj/item/organ/internal/O = thing
O.on_life()
for(var/organ_tag in internal_organ_datums)
var/datum/organ/datum_organ_var_name_idk = internal_organ_datums[organ_tag]
datum_organ_var_name_idk.on_life()

/mob/living/carbon/handle_diseases()
for(var/thing in viruses)
Expand Down
59 changes: 27 additions & 32 deletions code/modules/mob/living/carbon/human/human_life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -131,31 +131,31 @@

/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)

var/obj/item/organ/internal/L = get_organ_slot("lungs")
var/datum/organ/lungs/lung_datum = get_int_organ_datum(ORGAN_DATUM_LUNGS)

if(!L || L && (L.status & ORGAN_DEAD))
if(health >= HEALTH_THRESHOLD_CRIT)
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
else if(!HAS_TRAIT(src, TRAIT_NOCRITDAMAGE))
adjustOxyLoss(HUMAN_MAX_OXYLOSS)
if(lung_datum && !(lung_datum.linked_organ.status & ORGAN_DEAD))
lung_datum.check_breath(breath, src)
return

// We have no lungs, or our lungs are dead!
if(health >= HEALTH_THRESHOLD_CRIT)
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
else if(!HAS_TRAIT(src, TRAIT_NOCRITDAMAGE))
adjustOxyLoss(HUMAN_MAX_OXYLOSS)

if(dna.species)
var/datum/species/S = dna.species
if(dna.species)
var/datum/species/S = dna.species

if(S.breathid == "o2")
switch(S.breathid)
if("o2")
throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else if(S.breathid == "tox")
if("tox")
throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else if(S.breathid == "co2")
if("co2") // currently unused
throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else if(S.breathid == "n2")
if("n2")
throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro)

return FALSE
else
if(istype(L, /obj/item/organ/internal/lungs))
var/obj/item/organ/internal/lungs/lun = L
lun.check_breath(breath, src)
return FALSE

// USED IN DEATHWHISPERS
/mob/living/carbon/human/proc/isInCrit()
Expand Down Expand Up @@ -796,14 +796,13 @@
H.fakevomit()

/mob/living/carbon/human/proc/handle_heartbeat()
var/client/C = src.client
if(C && C.prefs.sound & SOUND_HEARTBEAT) //disable heartbeat by pref
var/obj/item/organ/internal/heart/H = get_int_organ(/obj/item/organ/internal/heart)
if(client && client.prefs.sound & SOUND_HEARTBEAT) //disable heartbeat by pref
var/datum/organ/heart/H = get_int_organ_datum(ORGAN_DATUM_HEART)

if(!H) //H.status will runtime if there is no H (obviously)
return

if(H.is_robotic()) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people.
if(H.linked_organ.is_robotic()) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people.
if(isinspace())
//PULSE_THREADY - maximum value for pulse, currently it 5.
//High pulse value corresponds to a fast rate of heartbeat.
Expand All @@ -816,7 +815,6 @@

else
heartbeat++
return
return

if(pulse == PULSE_NONE)
Expand Down Expand Up @@ -851,21 +849,18 @@
if(!can_heartattack())
return FALSE

var/obj/item/organ/internal/heart/heart = get_int_organ(/obj/item/organ/internal/heart)
if(!istype(heart) || (heart.status & ORGAN_DEAD) || !heart.beating)
var/datum/organ/heart/heart_datum = get_int_organ_datum(ORGAN_DATUM_HEART)
if(!istype(heart_datum) || (heart_datum.linked_organ.status & ORGAN_DEAD))
return TRUE

return FALSE
return !heart_datum.beating


/mob/living/carbon/human/proc/set_heartattack(status)
if(!can_heartattack())
return FALSE

var/obj/item/organ/internal/heart/heart = get_int_organ(/obj/item/organ/internal/heart)
if(!istype(heart))
return FALSE

heart.beating = !status
var/datum/organ/heart/heart_datum = get_int_organ_datum(ORGAN_DATUM_HEART)
heart_datum?.change_beating(!status)

/mob/living/carbon/human/handle_heartattack()
if(!can_heartattack() || !undergoing_cardiac_arrest() || reagents.has_reagent("corazone"))
Expand Down
18 changes: 7 additions & 11 deletions code/modules/mob/living/carbon/human/human_mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1207,20 +1207,16 @@
..()

/mob/living/carbon/human/proc/is_lung_ruptured()
var/obj/item/organ/internal/lungs/L = get_int_organ(/obj/item/organ/internal/lungs)
if(!L)
return 0
var/datum/organ/lungs/L = get_int_organ_datum(ORGAN_DATUM_LUNGS)

return L.is_bruised()
return L?.linked_organ.is_bruised()

/mob/living/carbon/human/proc/rupture_lung()
var/obj/item/organ/internal/lungs/L = get_int_organ(/obj/item/organ/internal/lungs)
if(!L)
return 0

if(!L.is_bruised())
L.custom_pain("You feel a stabbing pain in your chest!")
L.damage = L.min_bruised_damage
var/datum/organ/lungs/L = get_int_organ_datum(ORGAN_DATUM_LUNGS)
if(L && !L.linked_organ.is_bruised())
var/obj/item/organ/external/affected = get_organ("chest")
affected.custom_pain("You feel a stabbing pain in your chest!")
L.linked_organ.damage = L.linked_organ.min_bruised_damage

/mob/living/carbon/human/cuff_resist(obj/item/I)
if(HAS_TRAIT(src, TRAIT_HULK))
Expand Down
11 changes: 0 additions & 11 deletions code/modules/mob/living/carbon/human/human_organs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,6 @@ old_ue: Set this to a UE string, and this proc will overwrite the dna of organs
if(assimilate || O.dna.unique_enzymes == ue_to_compare)
O.set_dna(dna)

/*
Given the name of an organ, returns the external organ it's contained in
I use this to standardize shadowling dethrall code
-- Crazylemon
*/
/mob/living/carbon/human/proc/named_organ_parent(organ_name)
if(!get_int_organ_tag(organ_name))
return null
var/obj/item/organ/internal/O = get_int_organ_tag(organ_name)
return O.parent_organ

/mob/living/carbon/human/has_organic_damage()
var/robo_damage = 0
var/perma_injury_damage = 0
Expand Down
4 changes: 2 additions & 2 deletions code/modules/mob/living/carbon/human/human_say.dm
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@
return TRUE
// how do species that don't breathe talk? magic, that's what.
var/breathes = (!HAS_TRAIT(src, TRAIT_NOBREATH))
var/obj/item/organ/internal/L = get_organ_slot("lungs")
var/datum/organ/lungs/L = get_int_organ_datum(ORGAN_DATUM_LUNGS)
if(HAS_TRAIT(src, TRAIT_MUTE))
return FALSE
if((breathes && !L) || breathes && L && (L.status & ORGAN_DEAD))
if(breathes && (!L || L.linked_organ.status & ORGAN_DEAD))
return FALSE
if(mind)
return !mind.miming
Expand Down
4 changes: 1 addition & 3 deletions code/modules/mob/living/carbon/human/species/slimepeople.dm
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@

vision_organ = null
has_organ = list(
"heart" = /obj/item/organ/internal/heart/slime,
"brain" = /obj/item/organ/internal/brain/slime,
"lungs" = /obj/item/organ/internal/lungs/slime
"brain" = /obj/item/organ/internal/brain/slime
)
mutantears = null
suicide_messages = list(
Expand Down
1 change: 1 addition & 0 deletions code/modules/reagents/chemistry/reagents/disease.dm
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
if(volume > 4.5)
if(ishuman(M))
var/mob/living/carbon/human/H = M
// im not going to make this an organ datum, so that slime people dont get their brain instantly deleted
var/obj/item/organ/internal/heart/ate_heart = H.get_int_organ(/obj/item/organ/internal/heart)
if(ate_heart)
ate_heart.remove(H)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/station_goals/dna_vault.dm
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ GLOBAL_LIST_INIT(non_simple_animals, typecacheof(list(/mob/living/carbon/human/m
switch(upgrade_type)
if(VAULT_TOXIN)
to_chat(H, "<span class='notice'>You feel resistant to airborne toxins.</span>")
var/obj/item/organ/internal/lungs/L = H.get_int_organ(/obj/item/organ/internal/lungs)
var/datum/organ/lungs/L = H.get_int_organ_datum(ORGAN_DATUM_LUNGS)
if(L)
L.tox_breath_dam_min = 0
L.tox_breath_dam_max = 0
Expand Down
Loading

0 comments on commit 79a7558

Please sign in to comment.