Skip to content

Commit

Permalink
[MIRROR] Heart code cleanup [MDB IGNORE] (#641)
Browse files Browse the repository at this point in the history
* Heart code cleanup  (#79602)

---------

Co-authored-by: SkyratBot <[email protected]>
Co-authored-by: MrMelbert <[email protected]>
  • Loading branch information
3 people authored Nov 15, 2023
1 parent 1ef4bd9 commit 0cf6971
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 71 deletions.
5 changes: 1 addition & 4 deletions code/game/machinery/dna_infuser/organ_sets/fly_organs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,7 @@
name = odd_organ_name()
icon_state = FLY_INFUSED_ORGAN_ICON
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/fly)

/obj/item/organ/internal/heart/fly/update_icon_state()
SHOULD_CALL_PARENT(FALSE)
return //don't set icon thank you
AddElement(/datum/element/update_icon_blocker)

/obj/item/organ/internal/lungs/fly
desc = FLY_INFUSED_ORGAN_DESC
Expand Down
8 changes: 4 additions & 4 deletions code/modules/antagonists/abductor/equipment/gland.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
icon = 'icons/obj/antags/abductor.dmi'
icon_state = "gland"
organ_flags = ORGAN_ROBOTIC // weird?
beating = TRUE
/// Shows name of the gland as well as a description of what it does upon examination by abductor scientists and observers.
var/abductor_hint = "baseline placebo referencer"

Expand All @@ -26,12 +25,16 @@
/obj/item/organ/internal/heart/gland/Initialize(mapload)
. = ..()
icon_state = pick(list("health", "spider", "slime", "emp", "species", "egg", "vent", "mindshock", "viral"))
AddElement(/datum/element/update_icon_blocker)

/obj/item/organ/internal/heart/gland/examine(mob/user)
. = ..()
if(HAS_MIND_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING) || isobserver(user))
. += span_notice("It is \a [abductor_hint]")

/obj/item/organ/internal/heart/gland/Stop()
return FALSE

/obj/item/organ/internal/heart/gland/proc/ownerCheck()
if(ishuman(owner))
return TRUE
Expand Down Expand Up @@ -102,9 +105,6 @@
update_gland_hud()

/obj/item/organ/internal/heart/gland/on_life(seconds_per_tick, times_fired)
if(!beating)
// alien glands are immune to stopping.
beating = TRUE
if(!active)
return
if(!ownerCheck())
Expand Down
8 changes: 2 additions & 6 deletions code/modules/antagonists/nightmare/nightmare_organs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
/obj/item/organ/internal/heart/nightmare
name = "heart of darkness"
desc = "An alien organ that twists and writhes when exposed to light."
icon = 'icons/obj/medical/organs/organs.dmi'
icon_state = "demon_heart-on"
base_icon_state = "demon_heart"
visual = TRUE
color = "#1C1C1C"
decay_factor = 0
Expand All @@ -60,10 +60,6 @@
/// The armblade granted to the host of this heart.
var/obj/item/light_eater/blade

/obj/item/organ/internal/heart/nightmare/Initialize(mapload)
AddElement(/datum/element/update_icon_blocker)
return ..()

/obj/item/organ/internal/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
if(M != user)
return ..()
Expand Down Expand Up @@ -94,7 +90,7 @@
QDEL_NULL(blade)

/obj/item/organ/internal/heart/nightmare/Stop()
return 0
return FALSE

/obj/item/organ/internal/heart/nightmare/on_death(seconds_per_tick, times_fired)
if(!owner)
Expand Down
4 changes: 2 additions & 2 deletions code/modules/clothing/neck/_neck.dm
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@

//assess heart
if(body_part == BODY_ZONE_CHEST)//if we're listening to the chest
if(isnull(heart) || !heart.beating || carbon_patient.stat == DEAD)
if(isnull(heart) || !heart.is_beating() || carbon_patient.stat == DEAD)
render_list += "<span class='danger ml-1'>You don't hear a heartbeat!</span>\n"//they're dead or their heart isn't beating
else if(heart.damage > 10 || carbon_patient.blood_volume <= BLOOD_VOLUME_OKAY)
render_list += "<span class='danger ml-1'>You hear a weak heartbeat.</span>\n"//their heart is damaged, or they have critical blood
Expand Down Expand Up @@ -289,7 +289,7 @@
user.visible_message(span_notice("[user] presses their fingers against [carbon_patient]'s [body_part]."), ignored_mobs = user)

//assess pulse (heart & blood level)
if(isnull(heart) || !heart.beating || carbon_patient.blood_volume <= BLOOD_VOLUME_OKAY || carbon_patient.stat == DEAD)
if(isnull(heart) || !heart.is_beating() || carbon_patient.blood_volume <= BLOOD_VOLUME_OKAY || carbon_patient.stat == DEAD)
render_list += "<span class='danger ml-1'>You can't find a pulse!</span>\n"//they're dead, their heart isn't beating, or they have critical blood
else
if(heart.damage > 10)
Expand Down
5 changes: 2 additions & 3 deletions code/modules/mob/living/carbon/human/death.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift)
if(stat == DEAD)
return
stop_sound_channel(CHANNEL_HEARTBEAT)
var/obj/item/organ/internal/heart/H = get_organ_slot(ORGAN_SLOT_HEART)
if(H)
H.beat = BEAT_NONE
var/obj/item/organ/internal/heart/human_heart = get_organ_slot(ORGAN_SLOT_HEART)
human_heart?.beat = BEAT_NONE

. = ..()

Expand Down
15 changes: 12 additions & 3 deletions code/modules/mob/living/carbon/life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -803,12 +803,19 @@
*/
/mob/living/carbon/proc/undergoing_cardiac_arrest()
var/obj/item/organ/internal/heart/heart = get_organ_slot(ORGAN_SLOT_HEART)
if(istype(heart) && heart.beating)
if(istype(heart) && heart.is_beating())
return FALSE
else if(!needs_heart())
return FALSE
return TRUE

/**
* Causes the mob to either start or stop having a heart attack.
*
* status - Pass TRUE to start a heart attack, or FALSE to stop one.
*
* Returns TRUE if heart status was changed (heart attack -> no heart attack, or visa versa)
*/
/mob/living/carbon/proc/set_heartattack(status)
if(!can_heartattack())
return FALSE
Expand All @@ -817,5 +824,7 @@
if(!istype(heart))
return FALSE

heart.beating = !status
return TRUE
if(status)
return heart.Stop()

return heart.Restart()
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/obj/item/organ/internal/appendix/golem
name = "internal forge"
desc = "This expanded digestive chamber allows golems to smelt minerals, provided that they are immersed in lava."
icon_state = "ethereal_heart"
icon_state = "ethereal_heart-off"
color = COLOR_GOLEM_GRAY
organ_flags = ORGAN_MINERAL
/// Action which performs smelting
Expand Down
115 changes: 71 additions & 44 deletions code/modules/surgery/organs/internal/heart/_heart.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,54 +10,84 @@
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = 2.5 * STANDARD_ORGAN_DECAY //designed to fail around 6 minutes after death

low_threshold_passed = "<span class='info'>Prickles of pain appear then die out from within your chest...</span>"
high_threshold_passed = "<span class='warning'>Something inside your chest hurts, and the pain isn't subsiding. You notice yourself breathing far faster than before.</span>"
now_fixed = "<span class='info'>Your heart begins to beat again.</span>"
high_threshold_cleared = "<span class='info'>The pain in your chest has died down, and your breathing becomes more relaxed.</span>"
low_threshold_passed = span_info("Prickles of pain appear then die out from within your chest...")
high_threshold_passed = span_warning("Something inside your chest hurts, and the pain isn't subsiding. You notice yourself breathing far faster than before.")
now_fixed = span_info("Your heart begins to beat again.")
high_threshold_cleared = span_info("The pain in your chest has died down, and your breathing becomes more relaxed.")

// Heart attack code is in code/modules/mob/living/carbon/human/life.dm
var/beating = TRUE
attack_verb_continuous = list("beats", "thumps")
attack_verb_simple = list("beat", "thump")
var/beat = BEAT_NONE//is this mob having a heatbeat sound played? if so, which?
var/failed = FALSE //to prevent constantly running failing code
var/operated = FALSE //whether the heart's been operated on to fix some of its damages

// Heart attack code is in code/modules/mob/living/carbon/human/life.dm

/// Whether the heart is currently beating.
/// Do not set this directly. Use Restart() and Stop() instead.
VAR_PRIVATE/beating = TRUE

/// is this mob having a heatbeat sound played? if so, which?
var/beat = BEAT_NONE
/// whether the heart's been operated on to fix some of its damages
var/operated = FALSE

/obj/item/organ/internal/heart/update_icon_state()
. = ..()
icon_state = "[base_icon_state]-[beating ? "on" : "off"]"
return ..()

/obj/item/organ/internal/heart/Remove(mob/living/carbon/heartless, special = 0)
. = ..()
if(!special)
addtimer(CALLBACK(src, PROC_REF(stop_if_unowned)), 120)
addtimer(CALLBACK(src, PROC_REF(stop_if_unowned)), 12 SECONDS)
beat = BEAT_NONE
owner?.stop_sound_channel(CHANNEL_HEARTBEAT)

/obj/item/organ/internal/heart/proc/stop_if_unowned()
if(!owner)
if(QDELETED(src))
return
if(IS_ROBOTIC_ORGAN(src))
return
if(isnull(owner))
Stop()

/obj/item/organ/internal/heart/attack_self(mob/user)
..()
. = ..()
if(.)
return

if(!beating)
user.visible_message("<span class='notice'>[user] squeezes [src] to \
make it beat again!</span>",span_notice("You squeeze [src] to make it beat again!"))
user.visible_message(
span_notice("[user] squeezes [src] to make it beat again!"),
span_notice("You squeeze [src] to make it beat again!"),
)
Restart()
addtimer(CALLBACK(src, PROC_REF(stop_if_unowned)), 80)
addtimer(CALLBACK(src, PROC_REF(stop_if_unowned)), 8 SECONDS)
return TRUE

/obj/item/organ/internal/heart/proc/Stop()
if(!beating)
return FALSE

beating = FALSE
update_appearance()
beat = BEAT_NONE
owner?.stop_sound_channel(CHANNEL_HEARTBEAT)
return TRUE

/obj/item/organ/internal/heart/proc/Restart()
if(beating)
return FALSE

beating = TRUE
update_appearance()
return TRUE

/obj/item/organ/internal/heart/OnEatFrom(eater, feeder)
. = ..()
beating = FALSE
update_appearance()
Stop()

/// Checks if the heart is beating.
/// Can be overridden to add more conditions for more complex hearts.
/obj/item/organ/internal/heart/proc/is_beating()
return beating

/obj/item/organ/internal/heart/on_life(seconds_per_tick, times_fired)
..()
Expand All @@ -66,34 +96,32 @@
if(!owner.needs_heart())
return

if(owner.client && beating)
failed = FALSE
var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE)
var/sound/fastbeat = sound('sound/health/fastbeat.ogg', repeat = TRUE)
// Handle "sudden" heart attack
if(!beating || (organ_flags & ORGAN_FAILING))
if(owner.can_heartattack() && Stop())
if(owner.stat == CONSCIOUS)
owner.visible_message(span_danger("[owner] clutches at [owner.p_their()] chest as if [owner.p_their()] heart is stopping!"))
to_chat(owner, span_userdanger("You feel a terrible pain in your chest, as if your heart has stopped!"))
return

// Beyond deals with sound effects, so nothing needs to be done if no client
if(isnull(owner.client))
return

if(owner.health <= owner.crit_threshold && beat != BEAT_SLOW)
if(owner.stat == SOFT_CRIT)
if(beat != BEAT_SLOW)
beat = BEAT_SLOW
owner.playsound_local(get_turf(owner), slowbeat, 40, 0, channel = CHANNEL_HEARTBEAT, use_reverb = FALSE)
to_chat(owner, span_notice("You feel your heart slow down..."))
if(beat == BEAT_SLOW && owner.health > owner.crit_threshold)
owner.stop_sound_channel(CHANNEL_HEARTBEAT)
beat = BEAT_NONE

if(owner.has_status_effect(/datum/status_effect/jitter))
if(owner.health > HEALTH_THRESHOLD_FULLCRIT && (!beat || beat == BEAT_SLOW))
owner.playsound_local(get_turf(owner), fastbeat, 40, 0, channel = CHANNEL_HEARTBEAT, use_reverb = FALSE)
beat = BEAT_FAST

else if(beat == BEAT_FAST)
owner.stop_sound_channel(CHANNEL_HEARTBEAT)
beat = BEAT_NONE

if(organ_flags & ORGAN_FAILING && owner.can_heartattack() && !(HAS_TRAIT(src, TRAIT_STABLEHEART))) //heart broke, stopped beating, death imminent... unless you have veins that pump blood without a heart
if(owner.stat == CONSCIOUS)
owner.visible_message(span_danger("[owner] clutches at [owner.p_their()] chest as if [owner.p_their()] heart is stopping!"), \
span_userdanger("You feel a terrible pain in your chest, as if your heart has stopped!"))
owner.set_heartattack(TRUE)
failed = TRUE
SEND_SOUND(owner, sound('sound/health/slowbeat.ogg', repeat = TRUE, channel = CHANNEL_HEARTBEAT, volume = 40))

else if(owner.stat == HARD_CRIT)
if(beat != BEAT_FAST && owner.has_status_effect(/datum/status_effect/jitter))
SEND_SOUND(owner, sound('sound/health/fastbeat.ogg', repeat = TRUE, channel = CHANNEL_HEARTBEAT, volume = 40))
beat = BEAT_FAST

else if(beat == BEAT_SLOW)
owner.stop_sound_channel(CHANNEL_HEARTBEAT)
beat = BEAT_NONE

/obj/item/organ/internal/heart/get_availability(datum/species/owner_species, mob/living/owner_mob)
return owner_species.mutantheart
Expand Down Expand Up @@ -222,4 +250,3 @@
owner.heal_overall_damage(brute = 15, burn = 15, required_bodytype = BODYTYPE_ORGANIC)
if(owner.reagents.get_reagent_amount(/datum/reagent/medicine/ephedrine) < 20)
owner.reagents.add_reagent(/datum/reagent/medicine/ephedrine, 10)

10 changes: 6 additions & 4 deletions code/modules/surgery/organs/internal/heart/heart_ethereal.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/obj/item/organ/internal/heart/ethereal
name = "crystal core"
icon_state = "ethereal_heart" //Welp. At least it's more unique in functionaliy.
icon_state = "ethereal_heart-on"
base_icon_state = "ethereal_heart"
visual = TRUE //This is used by the ethereal species for color
desc = "A crystal-like organ that functions similarly to a heart for Ethereals. It can revive its owner."

Expand All @@ -18,6 +19,7 @@
/obj/item/organ/internal/heart/ethereal/Initialize(mapload)
. = ..()
add_atom_colour(ethereal_color, FIXED_COLOUR_PRIORITY)
update_appearance()

/obj/item/organ/internal/heart/ethereal/Insert(mob/living/carbon/heart_owner, special = FALSE, drop_if_replaced = TRUE)
. = ..()
Expand All @@ -36,7 +38,7 @@

/obj/item/organ/internal/heart/ethereal/update_overlays()
. = ..()
var/mutable_appearance/shine = mutable_appearance(icon, icon_state = "[icon_state]_shine")
var/mutable_appearance/shine = mutable_appearance(icon, icon_state = "[base_icon_state]_overlay-[beating ? "on" : "off"]")
shine.appearance_flags = RESET_COLOR //No color on this, just pure white
. += shine

Expand Down Expand Up @@ -193,13 +195,13 @@
add_atom_colour(ethereal_heart.ethereal_color, FIXED_COLOUR_PRIORITY)
crystal_heal_timer = addtimer(CALLBACK(src, PROC_REF(heal_ethereal)), CRYSTALIZE_HEAL_TIME, TIMER_STOPPABLE)
set_light(4, 10, ethereal_heart.ethereal_color)
update_icon()
update_appearance(UPDATE_OVERLAYS)
flick("ethereal_crystal_forming", src)
addtimer(CALLBACK(src, PROC_REF(start_crystalization)), 1 SECONDS)

/obj/structure/ethereal_crystal/proc/start_crystalization()
being_built = FALSE
update_icon()
update_appearance(UPDATE_OVERLAYS)

/obj/structure/ethereal_crystal/atom_destruction(damage_flag)
playsound(get_turf(ethereal_heart.owner), 'sound/effects/ethereal_revive_fail.ogg', 100)
Expand Down
Binary file modified icons/obj/medical/organs/organs.dmi
Binary file not shown.

0 comments on commit 0cf6971

Please sign in to comment.