diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index b481ba7ddd..ea29e956b6 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -30,6 +30,8 @@ #define STATUS_EFFECT_FLESHMEND /datum/status_effect/fleshmend //Very fast healing; suppressed by fire, and heals less fire damage +#define STATUS_EFFECT_EXERCISED /datum/status_effect/exercised //Prevents heart disease + ///////////// // DEBUFFS // ///////////// diff --git a/code/datums/diseases/heart_failure.dm b/code/datums/diseases/heart_failure.dm new file mode 100644 index 0000000000..151e3a2591 --- /dev/null +++ b/code/datums/diseases/heart_failure.dm @@ -0,0 +1,59 @@ +/datum/disease/heart_failure + form = "Condition" + name = "Myocardial Infarction" + max_stages = 5 + stage_prob = 2 + cure_text = "Heart replacement surgery to cure. Defibrillation (or as a last resort, uncontrolled electric shocking) may also be effective after the onset of cardiac arrest. Corazone can also mitigate cardiac arrest." + agent = "Shitty Heart" + viable_mobtypes = list(/mob/living/carbon) + permeability_mod = 1 + desc = "If left untreated the subject will die!" + severity = "Dangerous!" + disease_flags = CAN_CARRY|CAN_RESIST + spread_flags = VIRUS_SPREAD_NON_CONTAGIOUS + visibility_flags = HIDDEN_PANDEMIC + required_organs = list(/obj/item/organ/heart) + var/sound = FALSE + +/datum/disease/heart_failure/stage_act() + ..() + var/obj/item/organ/heart/O = affected_mob.getorgan(/obj/item/organ/heart) + var/mob/living/carbon/H = affected_mob + if(O && H.can_heartattack()) + switch(stage) + if(1 to 2) + if(prob(2)) + to_chat(H, "You feel [pick("discomfort", "pressure", "a burning sensation", "pain")] in your chest.") + if(prob(2)) + to_chat(H, "You feel dizzy.") + H.confused += 6 + if(prob(3)) + to_chat(H, "You feel [pick("full", "nauseous", "sweaty", "weak", "tired", "short on breath", "uneasy")].") + if(3 to 4) + if(!sound) + H.playsound_local(H, 'sound/health/slowbeat.ogg',40,0, channel = CHANNEL_HEARTBEAT) + sound = TRUE + if(prob(3)) + to_chat(H, "You feel a sharp pain in your chest!") + if(prob(25)) + affected_mob.vomit(95) + H.emote("cough") + H.Knockdown(40) + H.losebreath += 4 + if(prob(3)) + to_chat(H, "You feel very weak and dizzy...") + H.confused += 8 + H.adjustStaminaLoss(40) + H.emote("cough") + if(5) + H.stop_sound_channel(CHANNEL_HEARTBEAT) + H.playsound_local(H, 'sound/effects/singlebeat.ogg', 100, 0) + if(H.stat == CONSCIOUS) + H.visible_message("[H] clutches at [H.p_their()] chest as if [H.p_their()] heart is stopping!") + H.adjustStaminaLoss(60) + H.reagents.add_reagent("corazone", 3) // To give the victim a final chance to shock their heart before losing consciousness + H.set_heartattack(TRUE) + cure() + + else + cure() \ No newline at end of file diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 9179b9bea4..e0ff751ce5 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -436,3 +436,17 @@ name = "Fleshmend" desc = "Our wounds are rapidly healing. This effect is prevented if we are on fire." icon_state = "fleshmend" + +/datum/status_effect/exercised + id = "Exercised" + duration = 1200 + alert_type = null + +/datum/status_effect/exercised/on_creation(mob/living/new_owner, ...) + . = ..() + STOP_PROCESSING(SSfastprocess, src) + START_PROCESSING(SSprocessing, src) //this lasts 20 minutes, so SSfastprocess isn't needed. + +/datum/status_effect/exercised/Destroy() + . = ..() + STOP_PROCESSING(SSprocessing, src) \ No newline at end of file diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm new file mode 100644 index 0000000000..c934dceb7a --- /dev/null +++ b/code/modules/events/heart_attack.dm @@ -0,0 +1,23 @@ +/datum/round_event_control/heart_attack + name = "Random Heart Attack" + typepath = /datum/round_event/heart_attack + weight = 20 + max_occurrences = 2 + earliest_start = 12000 + min_players = 40 // To avoid shafting lowpop + +/datum/round_event/heart_attack/start() + var/list/heart_attack_contestants = list() + for(var/mob/living/carbon/H in shuffle(GLOB.player_list)) + if(!H.client || H.stat == DEAD || H.InCritical() || !H.can_heartattack() || H.has_status_effect(STATUS_EFFECT_EXERCISED) || (/datum/disease/heart_failure in H.viruses) || H.undergoing_cardiac_arrest()) + continue + if(H.satiety <= -100) + heart_attack_contestants[H] = 1.15 + else + heart_attack_contestants[H] = 1 + + if(LAZYLEN(heart_attack_contestants)) + var/mob/living/carbon/C = pickweight(heart_attack_contestants) + var/datum/disease/D = new /datum/disease/heart_failure + C.ForceContractDisease(D) + notify_ghosts("[C] is beginning to have a heart attack!", enter_link="(Click to orbit)", source=C, action=NOTIFY_ORBIT) \ No newline at end of file diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index b148495f44..a10735f6bb 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -8,9 +8,10 @@ var/list/hit_sounds = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg',\ 'sound/weapons/punch1.ogg', 'sound/weapons/punch2.ogg', 'sound/weapons/punch3.ogg', 'sound/weapons/punch4.ogg') -/obj/structure/punching_bag/attack_hand(mob/user as mob) - flick("[icon_state]2", src) - playsound(src.loc, pick(src.hit_sounds), 25, 1, -1) +/obj/structure/punching_bag/attack_hand(mob/living/user) + flick("[icon_state]2", src) + playsound(src.loc, pick(src.hit_sounds), 25, 1, -1) + user.apply_status_effect(STATUS_EFFECT_EXERCISED) /obj/structure/stacklifter name = "Weight Machine" @@ -49,6 +50,7 @@ var/finishmessage = pick("You feel stronger!","You feel like you can take on the world!","You feel robust!","You feel indestructible!") icon_state = "fitnesslifter" to_chat(user, finishmessage) + user.apply_status_effect(STATUS_EFFECT_EXERCISED) /obj/structure/weightlifter name = "Weight Machine" @@ -94,3 +96,4 @@ icon_state = "fitnessweight" cut_overlay(swole_overlay) to_chat(user, "[finishmessage]") + user.apply_status_effect(STATUS_EFFECT_EXERCISED) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 3a49badc77..a36ad80045 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -467,6 +467,9 @@ /mob/living/carbon/proc/can_heartattack() if(dna && dna.species && (NOBLOOD in dna.species.species_traits)) //not all carbons have species! return FALSE + var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART) + if(!heart || heart.synthetic) + return FALSE return TRUE /mob/living/carbon/proc/undergoing_cardiac_arrest() diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 5da89f125f..f36d9c7a14 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -149,6 +149,7 @@ name = "cybernetic heart" desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make." icon_state = "heart-c" + synthetic = TRUE /obj/item/organ/heart/cybernetic/emp_act() Stop() @@ -156,6 +157,7 @@ /obj/item/organ/heart/freedom name = "heart of freedom" desc = "This heart pumps with the passion to give... something freedom." + synthetic = TRUE //the power of freedom prevents heart attacks var/min_next_adrenaline = 0 /obj/item/organ/heart/freedom/on_life() diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index d2de50ce3e..9dceb5ceda 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -67,6 +67,7 @@ name = "cybernetic liver" icon_state = "liver-c" desc = "An electronic device designed to mimic the functions of a human liver. It has no benefits over an organic liver, but is easy to produce." + synthetic = TRUE /obj/item/organ/liver/cybernetic/upgraded name = "upgraded cybernetic liver" diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index f49b041b49..f492d99b8e 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -359,6 +359,7 @@ name = "cybernetic lungs" desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement." icon_state = "lungs-c" + synthetic = TRUE /obj/item/organ/lungs/cybernetic/emp_act() owner.losebreath = 20 diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index a384845281..fcaf89c61c 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -11,6 +11,7 @@ var/vital = 0 //Was this organ implanted/inserted/etc, if true will not be removed during species change. var/external = FALSE + var/synthetic = FALSE // To distinguish between organic and synthetic organs /obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE) diff --git a/tgstation.dme b/tgstation.dme index 64766bac2b..6344f71e12 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -373,6 +373,7 @@ #include "code\datums\diseases\flu.dm" #include "code\datums\diseases\fluspanish.dm" #include "code\datums\diseases\gbs.dm" +#include "code\datums\diseases\heart_failure.dm" #include "code\datums\diseases\magnitis.dm" #include "code\datums\diseases\parrotpossession.dm" #include "code\datums\diseases\pierrot_throat.dm" @@ -1453,6 +1454,7 @@ #include "code\modules\events\false_alarm.dm" #include "code\modules\events\ghost_role.dm" #include "code\modules\events\grid_check.dm" +#include "code\modules\events\heart_attack.dm" #include "code\modules\events\immovable_rod.dm" #include "code\modules\events\ion_storm.dm" #include "code\modules\events\major_dust.dm"