diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 18033f79479b..1e8a554c95bd 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -36,8 +36,7 @@
HM.on_life(seconds_per_tick, times_fired)
if(stat != DEAD)
- //heart attack stuff
- handle_heart(seconds_per_tick, times_fired)
+ // handle_heart(seconds_per_tick, times_fired) // NON-MODULE CHANGE
handle_liver(seconds_per_tick, times_fired)
dna.species.spec_life(src, seconds_per_tick, times_fired) // for mutantraces
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 12d6fa56d181..3d39e161c3bf 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1121,7 +1121,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(attacker_style?.help_act(user, target) == MARTIAL_ATTACK_SUCCESS)
return TRUE
- if(target.body_position == STANDING_UP || target.appears_alive())
+ if(!target.undergoing_cardiac_arrest() && (target.body_position == STANDING_UP || target.appears_alive())) // NON-MODULE CHANGE
target.help_shake_act(user)
if(target != user)
log_combat(user, target, "shaken")
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 9bf815d529f6..6cb626643de6 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -778,4 +778,9 @@
if(!istype(heart))
return
- heart.beating = !status
+ // NON-MODULE CHANGE START
+ if(status)
+ heart.Stop()
+ else
+ heart.Restart()
+ // NON-MODULE CHANGE END
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index c7831346cd63..98eb7b23971f 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -758,6 +758,6 @@
/// Helper to check if we seem to be alive or not
/mob/living/proc/appears_alive()
- return health >= 0 && !HAS_TRAIT(src, TRAIT_FAKEDEATH)
+ return stat != DEAD && !HAS_TRAIT(src, TRAIT_FAKEDEATH)
#undef IS_STUN_IMMUNE
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index 5faa98b24d08..d23957add378 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -56,8 +56,7 @@
/obj/item/organ/internal/heart/OnEatFrom(eater, feeder)
. = ..()
- beating = FALSE
- update_appearance()
+ Stop() // NON-MODULE CHANGE
/obj/item/organ/internal/heart/on_life(seconds_per_tick, times_fired)
..()
diff --git a/maplestation.dme b/maplestation.dme
index a349d1ad3ffc..9c0d7d64198d 100644
--- a/maplestation.dme
+++ b/maplestation.dme
@@ -5572,6 +5572,7 @@
#include "maplestation_modules\code\modules\language\japanese.dm"
#include "maplestation_modules\code\modules\language\language_holder.dm"
#include "maplestation_modules\code\modules\language\skrellian.dm"
+#include "maplestation_modules\code\modules\library\skill_learning\job_skillchips\medbay.dm"
#include "maplestation_modules\code\modules\library\skill_learning\job_skillchips\mining.dm"
#include "maplestation_modules\code\modules\loadouts\loadout_items\_limb_datums.dm"
#include "maplestation_modules\code\modules\loadouts\loadout_items\_loadout_categories.dm"
@@ -5632,6 +5633,9 @@
#include "maplestation_modules\code\modules\mob\living\carbon\human\human.dm"
#include "maplestation_modules\code\modules\mob\living\carbon\human\modular_sechud_icons.dm"
#include "maplestation_modules\code\modules\mob\living\carbon\human\skrell_hair.dm"
+#include "maplestation_modules\code\modules\mob\living\carbon\human\heart_rework\cpr.dm"
+#include "maplestation_modules\code\modules\mob\living\carbon\human\heart_rework\heart_attack.dm"
+#include "maplestation_modules\code\modules\mob\living\carbon\human\heart_rework\heart_overrides.dm"
#include "maplestation_modules\code\modules\mob\living\carbon\human\ornithid_features\armwings.dm"
#include "maplestation_modules\code\modules\mob\living\carbon\human\ornithid_features\avian_tails.dm"
#include "maplestation_modules\code\modules\mob\living\carbon\human\ornithid_features\plumage.dm"
diff --git a/maplestation_modules/code/__DEFINES/_module_defines.dm b/maplestation_modules/code/__DEFINES/_module_defines.dm
index d21d3f91e6f9..c8dd1faf9724 100644
--- a/maplestation_modules/code/__DEFINES/_module_defines.dm
+++ b/maplestation_modules/code/__DEFINES/_module_defines.dm
@@ -27,8 +27,11 @@
#define TOOLTIP_NO_DAMAGE "This item has very low force and is largely cosmetic."
#define TOOLTIP_RANDOM_COLOR "This item has a random color and will change every round."
-/// Modular traits
+// Modular traits
+/// Provides additional resistance to contracting diseases. Should be removed next upstream
#define TRAIT_DISEASE_RESISTANT "disease_resistant"
+/// Does not harm patients when undergoing CPR
+#define TRAIT_CPR_CERTIFIED "cpr_certified"
/// Bitflags for speech sounds
#define SOUND_NORMAL (1<<0)
diff --git a/maplestation_modules/code/datums/quirks/neutral.dm b/maplestation_modules/code/datums/quirks/neutral.dm
index 24d8ef53833b..7c14930b0e6b 100644
--- a/maplestation_modules/code/datums/quirks/neutral.dm
+++ b/maplestation_modules/code/datums/quirks/neutral.dm
@@ -27,3 +27,10 @@
//Will add named cardbinder, starting base 2 cards, packbox of 28 Red cards, 4 counters, and a paper with rules. Now in a handy box!
give_item_to_holder(card_binder, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
give_item_to_holder(/obj/item/storage/box/tdatet_starter, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
+
+/datum/quirk/cpr_certified
+ name = "CPR Certified"
+ desc = "You are certified to perform CPR on others independent of your job."
+ icon = FA_ICON_HEARTBEAT
+ value = 0
+ mob_trait = TRAIT_CPR_CERTIFIED
diff --git a/maplestation_modules/code/game/objects/structures/crate_lockers/closets/secure/quartermaster.dm b/maplestation_modules/code/game/objects/structures/crate_lockers/closets/secure/quartermaster.dm
index 704fc952c60a..a42c59887207 100644
--- a/maplestation_modules/code/game/objects/structures/crate_lockers/closets/secure/quartermaster.dm
+++ b/maplestation_modules/code/game/objects/structures/crate_lockers/closets/secure/quartermaster.dm
@@ -1,5 +1,4 @@
// -- Quartermaster locker stuff. --
/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
. = ..()
- new /obj/item/storage/box/skillchips/cargo(src)
new /obj/item/storage/bag/garment/magic/quartermaster(src) // done at the veeeery end for a reason.
diff --git a/maplestation_modules/code/modules/library/skill_learning/job_skillchips/medbay.dm b/maplestation_modules/code/modules/library/skill_learning/job_skillchips/medbay.dm
new file mode 100644
index 000000000000..561d5d3f83df
--- /dev/null
+++ b/maplestation_modules/code/modules/library/skill_learning/job_skillchips/medbay.dm
@@ -0,0 +1,76 @@
+/obj/item/skillchip/entrails_reader
+ complexity = 0 // who cares?
+
+/// Teaches you how to perform CPR without harming the patient
+/obj/item/skillchip/job/cpr
+ name = "CPR-Aid"
+ skill_name = "CPR Training"
+ skill_description = "Provides the user with the knowledge of how to safely perform CPR on a patient."
+ skill_icon = FA_ICON_HEARTBEAT
+ activate_message = span_notice("You feel more confident in your ability to perform CPR.")
+ deactivate_message = span_notice("You suddenly feel less confident in your ability to perform CPR.")
+ auto_traits = list(TRAIT_CPR_CERTIFIED)
+ complexity = 0 // it's pretty minor, all things considered
+
+/datum/outfit/job/doctor/New()
+ . = ..()
+ LAZYADD(skillchips, /obj/item/skillchip/job/cpr)
+
+/datum/outfit/job/paramedic/New()
+ . = ..()
+ LAZYADD(skillchips, /obj/item/skillchip/job/cpr)
+
+/datum/outfit/job/cmo/New()
+ . = ..()
+ LAZYADD(skillchips, /obj/item/skillchip/job/cpr)
+
+/obj/item/storage/box/skillchips/medbay
+ name = "box of medbay skillchips"
+ desc = "Contains spares of every medical job skillchip."
+
+/obj/item/storage/box/skillchips/medbay/PopulateContents()
+ new /obj/item/skillchip/job/cpr(src)
+ new /obj/item/skillchip/job/cpr(src)
+ new /obj/item/skillchip/job/cpr(src)
+ new /obj/item/skillchip/job/cpr(src)
+ new /obj/item/skillchip/entrails_reader(src)
+
+/obj/structure/closet/secure_closet/chief_medical/PopulateContents()
+ . = ..()
+ new /obj/item/storage/box/skillchips/medbay(src)
+
+/// Book that grants the same trait as a skillchip, since reasonably there's no need for it to be chip locked
+/obj/item/book/granter/cpr
+ name = "CPR Training Manual"
+ desc = "A book that teaches you how to perform CPR properly and safely."
+ icon_state = "book7"
+ remarks = list(
+ "Assess the situation for danger... But it's always dangerous on the station!",
+ "Make sure to check for a pulse and call for help before starting...",
+ "Thirty compressions followed by two breaths...",
+ "Match compressions to the beat of 'Staying Alive'... What?",
+ "Proper hand placement is crucial. Wait, are lizardperson hearts in the same location as humans?",
+ "Tilt the head back and pinch the nose before delivering breaths.",
+ "Let the chest return to its normal position after each compression.",
+ "Follow up with an AED if available.",
+ )
+ pages_to_mastery = 6
+ reading_time = 2 SECONDS
+ uses = INFINITY
+
+/obj/item/book/granter/cpr/can_learn(mob/living/user)
+ return !HAS_TRAIT_FROM(user, TRAIT_CPR_CERTIFIED, name)
+
+/obj/item/book/granter/cpr/on_reading_start(mob/living/user)
+ . = ..()
+ if(HAS_TRAIT(user, TRAIT_CPR_CERTIFIED))
+ to_chat(user, span_notice("You already know how to perform CPR, but it can't hurt to brush up."))
+
+/obj/item/book/granter/cpr/on_reading_finished(mob/living/user)
+ . = ..()
+ if(HAS_TRAIT(user, TRAIT_CPR_CERTIFIED))
+ to_chat(user, span_green("You remind yourself of the proper way to perform CPR safely."))
+ else
+ to_chat(user, span_green("You feel confident in your ability to perform CPR safely."))
+
+ ADD_TRAIT(user, TRAIT_CPR_CERTIFIED, name)
diff --git a/maplestation_modules/code/modules/library/skill_learning/job_skillchips/mining.dm b/maplestation_modules/code/modules/library/skill_learning/job_skillchips/mining.dm
index 872d34fba159..9366382d5da4 100644
--- a/maplestation_modules/code/modules/library/skill_learning/job_skillchips/mining.dm
+++ b/maplestation_modules/code/modules/library/skill_learning/job_skillchips/mining.dm
@@ -5,8 +5,8 @@
skill_name = "Off Station Pain Resistance"
skill_description = "For the adventurous in life, this skillchip provides a reduction in pain received when off the station."
skill_icon = "fist-raised"
- activate_message = "You feel like you can safely take on the unknown."
- deactivate_message = "You feel more vulnerable to the unknown."
+ activate_message = span_notice("You feel like you can safely take on the unknown.")
+ deactivate_message = span_notice("You feel more vulnerable to the unknown.")
/obj/item/skillchip/job/off_z_pain_resistance/on_activate(mob/living/carbon/user, silent = FALSE)
. = ..()
@@ -47,3 +47,7 @@
/obj/item/storage/box/skillchips/cargo/PopulateContents()
new /obj/item/skillchip/job/off_z_pain_resistance(src)
new /obj/item/skillchip/job/off_z_pain_resistance(src)
+
+/obj/structure/closet/secure_closet/quartermaster/PopulateContents()
+ . = ..()
+ new /obj/item/storage/box/skillchips/cargo(src)
diff --git a/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/cpr.dm b/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/cpr.dm
new file mode 100644
index 000000000000..fd0b7e32f415
--- /dev/null
+++ b/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/cpr.dm
@@ -0,0 +1,161 @@
+
+/mob/living/carbon/human/do_cpr(mob/living/carbon/human/target)
+ if(target == src)
+ return FALSE
+
+ if (DOING_INTERACTION_WITH_TARGET(src, target))
+ return FALSE
+
+ cpr_process(target, beat = 1) // begin at beat 1, skip the first breath
+ return TRUE
+
+/// Number of "beats" per CPR cycle
+/// This corresponds to N - 1 compressions and 1 breath
+#define BEATS_PER_CPR_CYCLE 16
+// Also I'm kinda cheating here because we do 15 compressions to 1 breath rather than 30 compressions to 2 breaths
+// But it's close enough to the real thing (ratio wise) that I'm OK with it
+
+/mob/living/carbon/human/proc/cpr_process(mob/living/carbon/human/target, beat = 0, panicking = FALSE)
+ set waitfor = FALSE
+
+ if (!target.appears_alive())
+ to_chat(src, span_warning("[target.name] is dead!"))
+ return
+
+ if(!panicking && target.stat != CONSCIOUS && beat >= BEATS_PER_CPR_CYCLE + 1)
+ to_chat(src, span_warning("[target] still isn't up[HAS_TRAIT(src, TRAIT_CPR_CERTIFIED) ? " - you pick up the pace." : "! You try harder!"]"))
+ panicking = TRUE
+
+ var/doafter_mod = panicking ? 0.5 : 1
+
+ var/doing_a_breath = FALSE
+ if(beat % BEATS_PER_CPR_CYCLE == 0)
+ if (is_mouth_covered())
+ to_chat(src, span_warning("Your mouth is covered, so you can only perform compressions!"))
+
+ else if (target.is_mouth_covered())
+ to_chat(src, span_warning("[p_their(TRUE)] mouth is covered, so you can only perform compressions!"))
+
+ else if (!get_organ_slot(ORGAN_SLOT_LUNGS))
+ to_chat(src, span_warning("You have no lungs to breathe with, so you can only perform compressions!"))
+
+ else if (HAS_TRAIT(src, TRAIT_NOBREATH))
+ to_chat(src, span_warning("You do not breathe, so you can only perform compressions!"))
+
+ else
+ doing_a_breath = TRUE
+
+ if(doing_a_breath)
+ visible_message(
+ span_notice("[src] attempts to give [target.name] a rescue breath!"),
+ span_notice("You attempt to give [target.name] a rescue breath as a part of CPR... Hold still!"),
+ )
+
+ if(!do_after(user = src, delay = doafter_mod * 6 SECONDS, target = target))
+ return
+
+ add_mood_event("saved_life", /datum/mood_event/saved_life)
+ visible_message(
+ span_notice("[src] delivers a rescue breath on [target.name]!"),
+ span_notice("You deliver a rescue breath on [target.name]."),
+ )
+
+ else
+ var/is_first_compression = beat % BEATS_PER_CPR_CYCLE == 1
+ if(is_first_compression)
+ visible_message(
+ span_notice("[src] attempts to give [target.name] chest compressions!"),
+ span_notice("You try to perform chest compressions as a part of CPR on [target.name]... Hold still!"),
+ )
+
+ if(!do_after(user = src, delay = doafter_mod * 1 SECONDS, target = target))
+ return
+
+ if(is_first_compression)
+ visible_message(
+ span_notice("[src] delivers chest compressions on [target.name]!"),
+ span_notice("You deliver chest compressions on [target.name]."),
+ )
+
+ target.apply_status_effect(/datum/status_effect/cpr_applied)
+
+ if(doing_a_breath)
+ if(HAS_TRAIT(target, TRAIT_NOBREATH))
+ to_chat(target, span_unconscious("You feel a breath of fresh air... which is a sensation you don't recognise..."))
+ else if (!target.get_organ_slot(ORGAN_SLOT_LUNGS))
+ to_chat(target, span_unconscious("You feel a breath of fresh air... but you don't feel any better..."))
+ else if(HAS_TRAIT(src, TRAIT_CPR_CERTIFIED))
+ target.adjustOxyLoss(-20)
+ to_chat(target, span_unconscious("You feel a breath of fresh air enter your lungs... It feels good..."))
+ else
+ target.adjustOxyLoss(-12)
+ to_chat(target, span_unconscious("You feel a breath of fresh air enter your lungs..."))
+
+ // Breath relieves some of the pressure on the chest
+ var/obj/item/bodypart/chest/chest = target.get_bodypart(BODY_ZONE_CHEST)
+ if(IS_ORGANIC_LIMB(chest))
+ to_chat(target, span_notice("You feel the pressure on your chest ease!"))
+ chest.heal_damage(brute = 3)
+ target.cause_pain(BODY_ZONE_CHEST, -2)
+
+ log_combat(src, target, "CPRed", addition = "(breath)")
+
+ else if(beat % (BEATS_PER_CPR_CYCLE / 4) == 0 && panicking)
+ var/obj/item/bodypart/chest/chest = target.get_bodypart(BODY_ZONE_CHEST)
+ if(IS_ORGANIC_LIMB(chest))
+ var/critical_success = prob(1) && target.undergoing_cardiac_arrest()
+ if(!HAS_TRAIT(src, TRAIT_CPR_CERTIFIED))
+ // Apply damage directly to chest. I would use apply damage but I can't, kinda
+ if(critical_success)
+ target.set_heartattack(FALSE)
+ to_chat(target, span_warning("You feel immense pressure on your chest, and a sudden wave of pain... and then relief."))
+ chest.receive_damage(brute = 6, wound_bonus = CANT_WOUND, damage_source = "chest compressions")
+ target.cause_pain(BODY_ZONE_CHEST, 12)
+
+ else
+ to_chat(target, span_warning("You feel pressure on your chest!"))
+ chest.receive_damage(brute = 3, wound_bonus = CANT_WOUND, damage_source = "chest compressions")
+ target.cause_pain(BODY_ZONE_CHEST, 2)
+
+ to_chat(src, span_warning("You bruise [target.name]'s chest with the pressure!"))
+
+ else if(critical_success)
+ target.set_heartattack(FALSE)
+ to_chat(target, span_warning("You pressure fade away from your chest... and then relief."))
+ target.cause_pain(BODY_ZONE_CHEST, 8)
+
+ log_combat(src, target, "CPRed", addition = "(compression)")
+
+ if(target.body_position != LYING_DOWN)
+ return
+ if(target.stat == CONSCIOUS)
+ return
+
+ cpr_process(target, beat + 1, panicking)
+
+#undef BEATS_PER_CPR_CYCLE
+
+/datum/status_effect/cpr_applied
+ id = "cpr"
+ alert_type = null
+ duration = 1 SECONDS
+ tick_interval = -1
+ status_type = STATUS_EFFECT_REFRESH
+
+/datum/status_effect/cpr_applied/on_apply()
+ if(!is_effective(owner))
+ return FALSE
+ return TRUE
+
+/datum/status_effect/cpr_applied/refresh(effect, ...)
+ if(!is_effective(owner))
+ return
+ return ..()
+
+/// Checks if CPR is effective against this mob
+/datum/status_effect/cpr_applied/proc/is_effective(mob/checking)
+ if(isnull(checking))
+ return FALSE
+ if(!checking.get_organ_slot(ORGAN_SLOT_HEART)) // A heart is required for CPR to pump your heart
+ return FALSE
+ return TRUE
diff --git a/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/heart_attack.dm b/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/heart_attack.dm
new file mode 100644
index 000000000000..d4eb1a9d04e1
--- /dev/null
+++ b/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/heart_attack.dm
@@ -0,0 +1,81 @@
+/datum/status_effect/heart_attack
+ id = "heart_attack"
+ alert_type = null
+ tick_interval = 2 SECONDS
+ /// TimerID for the initial knock out
+ VAR_FINAL/ko_timer
+
+/datum/status_effect/heart_attack/on_apply()
+ if(!iscarbon(owner))
+ return FALSE
+ var/mob/living/carbon/carbon_owner = owner
+ if(isnull(carbon_owner.dna?.species?.mutantheart))
+ return FALSE
+
+ RegisterSignal(owner, COMSIG_SPECIES_GAIN, PROC_REF(species_changed))
+ RegisterSignal(owner, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath))
+
+ // You get 1 tick of grace before you fall over due to your heart stopping
+ ko_timer = addtimer(CALLBACK(src, PROC_REF(delayed_ko)), initial(tick_interval), TIMER_STOPPABLE)
+ return TRUE
+
+/datum/status_effect/heart_attack/on_remove()
+ REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
+ deltimer(ko_timer)
+
+ UnregisterSignal(owner, COMSIG_SPECIES_GAIN)
+ UnregisterSignal(owner, COMSIG_CARBON_ATTEMPT_BREATHE)
+ UnregisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_NOBREATH))
+ UnregisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_NOBREATH))
+
+ if(!QDELING(owner))
+ owner.cause_pain(BODY_ZONE_CHEST, -20)
+
+/datum/status_effect/heart_attack/proc/delayed_ko()
+ if(!HAS_TRAIT(owner, TRAIT_NOBREATH))
+ ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
+ ko_timer = null
+
+ RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_NOBREATH), PROC_REF(gained_nobreath))
+ RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_NOBREATH), PROC_REF(lost_nobreath))
+
+/datum/status_effect/heart_attack/proc/species_changed(datum/source, datum/species/new_species, datum/species/old_species)
+ SIGNAL_HANDLER
+ if(isnull(new_species.mutantheart))
+ qdel(src)
+
+/datum/status_effect/heart_attack/proc/gained_nobreath(datum/source)
+ SIGNAL_HANDLER
+ REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
+
+/datum/status_effect/heart_attack/proc/lost_nobreath(datum/source)
+ SIGNAL_HANDLER
+ if(!HAS_TRAIT(owner, TRAIT_NOBREATH))
+ ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
+
+/datum/status_effect/heart_attack/proc/block_breath(datum/source)
+ SIGNAL_HANDLER
+
+ if(HAS_TRAIT(owner, TRAIT_NOBREATH))
+ return NONE
+
+ if(prob(10))
+ INVOKE_ASYNC(owner, TYPE_PROC_REF(/mob, emote), "gasp")
+
+ return COMSIG_CARBON_BLOCK_BREATH
+
+/datum/status_effect/heart_attack/tick(seconds_per_tick, times_fired)
+ seconds_per_tick = (initial(tick_interval) / 10) // to remove when upstream merge
+
+ if(ko_timer) // Not yet
+ return
+ if(owner.stat == DEAD || HAS_TRAIT(owner, TRAIT_STABLEHEART) || HAS_TRAIT(owner, TRAIT_NOBLOOD) || IS_IN_STASIS(owner))
+ return
+ if(owner.has_status_effect(/datum/status_effect/cpr_applied))
+ return
+
+ if(!HAS_TRAIT(owner, TRAIT_NOBREATH))
+ owner.adjustOxyLoss(4 * seconds_per_tick)
+
+ // Tissues die without blood circulation
+ owner.adjustBruteLoss(1 * seconds_per_tick)
diff --git a/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/heart_overrides.dm b/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/heart_overrides.dm
new file mode 100644
index 000000000000..05624ad034c0
--- /dev/null
+++ b/maplestation_modules/code/modules/mob/living/carbon/human/heart_rework/heart_overrides.dm
@@ -0,0 +1,41 @@
+/obj/item/organ/internal/heart/Stop()
+ if(!beating)
+ return
+
+ . = ..()
+ if(!. || !owner)
+ return
+
+ owner.apply_status_effect(/datum/status_effect/heart_attack)
+
+/obj/item/organ/internal/heart/Restart()
+ if(beating)
+ return
+
+ . = ..()
+ if(!. || !owner)
+ return
+
+ owner.remove_status_effect(/datum/status_effect/heart_attack)
+
+/obj/item/organ/internal/heart/on_insert(mob/living/carbon/organ_owner, special)
+ . = ..()
+ if(beating)
+ organ_owner.remove_status_effect(/datum/status_effect/heart_attack)
+
+/obj/item/organ/internal/heart/on_remove(mob/living/carbon/organ_owner, special)
+ . = ..()
+ if(!special)
+ organ_owner.apply_status_effect(/datum/status_effect/heart_attack)
+
+// Glands can't stop beating but they are cringe
+/obj/item/organ/internal/heart/gland/Stop()
+ return FALSE
+
+/*
+// I think this is un-necessary, so I'm commenting it out even if it's SUPPOSED to be a thing
+/mob/living/carbon/human/setup_organless_effects()
+ . = ..()
+ // You don't spawn with a heart, so, technically... You spawn with a heart attack
+ apply_status_effect(/datum/status_effect/heart_attack)
+*/