diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 51d9cc95802f2..9d8e16b6d5e88 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -570,3 +570,6 @@ GLOBAL_LIST_INIT(available_random_trauma_list, list( /// Messages when (something) lays an egg #define EGG_LAYING_MESSAGES list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.") + +/// Returns whether or not the given mob can succumb +#define CAN_SUCCUMB(target) (HAS_TRAIT(target, TRAIT_CRITICAL_CONDITION) && !HAS_TRAIT(target, TRAIT_NODEATH)) diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 9c42e2a4dc873..889c183b21e92 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -6,7 +6,8 @@ #define CONSCIOUS 0 #define SOFT_CRIT 1 #define UNCONSCIOUS 2 -#define DEAD 3 +#define HARD_CRIT 3 +#define DEAD 4 //Maximum healthiness an individual can have #define MAX_SATIETY 600 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index b0fe2d1f7c879..1f27dea77191d 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -143,6 +143,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_RESTRAINED "restrained" */ #define TRAIT_INCAPACITATED "incapacitated" +//In some kind of critical condition. Is able to succumb. +#define TRAIT_CRITICAL_CONDITION "critical-condition" //mob traits #define TRAIT_BLIND "blind" @@ -385,6 +387,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define CHOKEHOLD_TRAIT "chokehold" //trait associated to resting #define RESTING_TRAIT "resting" +//trait associated to a stat value or range of +#define STAT_TRAIT "stat" #define GLASSES_TRAIT "glasses" #define CURSE_TRAIT "eldritch" #define STATION_TRAIT "station-trait" diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 1bf046db6bafc..fe90cfb073746 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -328,6 +328,23 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." balloon_alert(owner, "You moved out of range of [offerer]!") owner.clear_alert("[offerer]") +/// Gives the player the option to succumb while in critical condition +/atom/movable/screen/alert/succumb + name = "Succumb" + desc = "Shuffle off this mortal coil." + icon_state = "succumb" + +/atom/movable/screen/alert/succumb/Click() + if (isobserver(usr)) + return + var/mob/living/living_owner = owner + var/last_whisper = tgui_input_text(usr, "Do you have any last words?", "Goodnight, Sweet Prince") + if (isnull(last_whisper) || !CAN_SUCCUMB(living_owner)) + return + if (length(last_whisper)) + living_owner.say("#[last_whisper]") + living_owner.succumb(whispered = length(last_whisper) > 0) + //ALIENS /atom/movable/screen/alert/alien_tox diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 7ea3f13657656..d3081a124e5a9 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -123,10 +123,11 @@ return power if(M.IsSleeping()) return power * 0.25 //Voluntary unconsciousness yields lower healing. - if(M.stat == UNCONSCIOUS) - return power * 0.9 - if(M.stat == SOFT_CRIT) - return power * 0.5 + switch(M.stat) + if(UNCONSCIOUS, HARD_CRIT) + return power * 0.9 + if(SOFT_CRIT) + return power * 0.5 if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma) if(M.stat != DEAD) to_chat(M, "You feel yourself slip into a deep, regenerative slumber.") diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index c9bca7be5b732..0c53aea611c97 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -161,7 +161,7 @@ switch(user.stat) if(SOFT_CRIT) to_chat(user, "You cannot [key] while in a critical condition.") - if(UNCONSCIOUS) + if(UNCONSCIOUS, HARD_CRIT) to_chat(user, "You cannot [key] while unconscious.") if(DEAD) to_chat(user, "You cannot [key] while dead.") diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index ec1e01760f10b..6247c56e05f28 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -355,7 +355,7 @@ switch(stat) if(CONSCIOUS) holder.icon_state = "hudstat" - if(UNCONSCIOUS) + if(UNCONSCIOUS, HARD_CRIT) holder.icon_state = "hudoffline" else holder.icon_state = "huddead2" diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 4e1fbb3eb4f60..dcf555e3bb7a8 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -714,7 +714,7 @@ if(L.suiciding) //Suicider msg += "[L.name] ([L.key]), the [L.job] (Suicide)\n" failed = TRUE //Disconnected client - if(!failed && L.stat == UNCONSCIOUS) + if(!failed && (L.stat == UNCONSCIOUS || L.stat == HARD_CRIT)) msg += "[L.name] ([L.key]), the [L.job] (Dying)\n" failed = TRUE //Unconscious if(!failed && L.stat == DEAD) diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index bc00f8f9d6e47..2cb0c5c1c178c 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -121,7 +121,7 @@ if(SOFT_CRIT) data["patient"]["stat"] = "Conscious" data["patient"]["statstate"] = "average" - if(UNCONSCIOUS) + if(UNCONSCIOUS, HARD_CRIT) data["patient"]["stat"] = "Unconscious" data["patient"]["statstate"] = "average" if(DEAD) diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 6ae9cc445868e..40275522c39c4 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -103,7 +103,7 @@ switch (occupier.stat) if (CONSCIOUS) add_overlay("ai-fixer-full") - if (UNCONSCIOUS) + if (UNCONSCIOUS, HARD_CRIT) add_overlay("ai-fixer-404") else add_overlay("ai-fixer-empty") diff --git a/code/modules/admin/admin_more_info.dm b/code/modules/admin/admin_more_info.dm index 2bbc33639bad2..dae31031eaaaa 100644 --- a/code/modules/admin/admin_more_info.dm +++ b/code/modules/admin/admin_more_info.dm @@ -32,7 +32,9 @@ if(SOFT_CRIT) status = "Dying" if(UNCONSCIOUS) - status = "[L.InCritical() ? "Unconscious and Dying" : "Unconscious"]" + status = "Unconscious" + if(HARD_CRIT) + status = "Unconscious and Dying" if(DEAD) status = "Dead" health_description = "Status = [status]" diff --git a/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm b/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm index 41a28d5204e14..66625f40fbdaf 100644 --- a/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm +++ b/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm @@ -35,7 +35,7 @@ /datum/reagent/blob/zombifying_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O) reac_volume = ..() M.apply_damage(0.6*reac_volume, TOX) - if(O && ishuman(M) && M.stat == UNCONSCIOUS) + if(O && ishuman(M) && (M.stat == UNCONSCIOUS || M.stat == HARD_CRIT)) M.investigate_log("has been killed by distributed neurons (blob).", INVESTIGATE_DEATHS) M.death() //sleeping in a fight? bad plan. var/points = rand(5, 10) diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index 4cdf3e9c94aa8..0575741d4fe6d 100644 --- a/code/modules/antagonists/changeling/changeling_power.dm +++ b/code/modules/antagonists/changeling/changeling_power.dm @@ -13,7 +13,8 @@ var/req_dna = 0 //amount of dna needed to use this ability. Changelings always have atleast 1 var/req_human = 0 //if you need to be human to use this ability var/req_absorbs = 0 //similar to req_dna, but only gained from absorbing, not DNA sting - var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD + ///Maximum stat before the ability is blocked. For example, `UNCONSCIOUS` prevents it from being used when in hard crit or dead, while `DEAD` allows the ability to be used on any stat values. + var/req_stat = CONSCIOUS var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag var/active = FALSE//used by a few powers that toggle diff --git a/code/modules/antagonists/changeling/powers/fleshmend.dm b/code/modules/antagonists/changeling/powers/fleshmend.dm index ebb46704f096c..29563833a1607 100644 --- a/code/modules/antagonists/changeling/powers/fleshmend.dm +++ b/code/modules/antagonists/changeling/powers/fleshmend.dm @@ -5,7 +5,7 @@ button_icon_state = "fleshmend" chemical_cost = 25 dna_cost = 2 - req_stat = UNCONSCIOUS + req_stat = HARD_CRIT //Starts healing you every second for 10 seconds. //Can be used whilst unconscious. diff --git a/code/modules/antagonists/changeling/powers/panacea.dm b/code/modules/antagonists/changeling/powers/panacea.dm index 4b91eaff2cf3d..182570df096dd 100644 --- a/code/modules/antagonists/changeling/powers/panacea.dm +++ b/code/modules/antagonists/changeling/powers/panacea.dm @@ -5,7 +5,7 @@ button_icon_state = "panacea" chemical_cost = 20 dna_cost = 1 - req_stat = UNCONSCIOUS + req_stat = HARD_CRIT //Heals the things that the other regenerative abilities don't. /datum/action/changeling/panacea/sting_action(mob/user) diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm index 483751c0e792d..787e04af944b6 100644 --- a/code/modules/antagonists/changeling/powers/regenerate.dm +++ b/code/modules/antagonists/changeling/powers/regenerate.dm @@ -5,7 +5,7 @@ button_icon_state = "regenerate" chemical_cost = 10 dna_cost = 1 - req_stat = UNCONSCIOUS + req_stat = HARD_CRIT /datum/action/changeling/regenerate/sting_action(mob/living/user) ..() diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index f97c938e930fc..fe1df7332da53 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -930,7 +930,7 @@ structure_check() searches for nearby cultist structures required for the invoca to_chat(new_human, "You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar'Sie, and you are to serve them at all costs.") while(!QDELETED(src) && !QDELETED(user) && !QDELETED(new_human) && (user in T)) - if(user.stat || new_human.InCritical()) + if(user.stat != CONSCIOUS || HAS_TRAIT(new_human, TRAIT_CRITICAL_CONDITION)) break user.apply_damage(0.1, BRUTE) sleep(1) diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index 333f86952315c..65e1aa44d4c56 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -404,7 +404,7 @@ continue if(possible_target in target_blacklist) continue - if(player.stat == DEAD || player.InFullCritical()) + if(player.stat >= HARD_CRIT) //Hardcrit or worse (like being dead lmao) continue . += possible_target diff --git a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm index 5a3ea9317ee01..313c32721aa97 100644 --- a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm +++ b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm @@ -24,7 +24,7 @@ if(!target.mind || !target.client || target.stat == DEAD || !target.on_fire || IS_HERETIC_OR_MONSTER(target)) continue //This is essentially a death mark, use this to finish your opponent quicker. - if(target.InCritical() && !HAS_TRAIT(target, TRAIT_NODEATH)) + if(HAS_TRAIT(target, TRAIT_CRITICAL_CONDITION) && !HAS_TRAIT(target, TRAIT_NODEATH)) target.investigate_log("has been killed by fiery rebirth.", INVESTIGATE_DEATHS) target.death() diff --git a/code/modules/antagonists/holoparasite/holoparasite_team.dm b/code/modules/antagonists/holoparasite/holoparasite_team.dm index b54dafd77aab5..2f049cee9f068 100644 --- a/code/modules/antagonists/holoparasite/holoparasite_team.dm +++ b/code/modules/antagonists/holoparasite/holoparasite_team.dm @@ -80,7 +80,7 @@ info["escaped"] = holder.owner.force_escaped || summoner_turf.onCentCom() || summoner_turf.onSyndieBase() if(summoner.stat != DEAD) info["stat"] = "alive" - info["crit"] = summoner.InCritical() + info["crit"] = HAS_TRAIT(summoner, TRAIT_CRITICAL_CONDITION) SSblackbox.record_feedback("associative", "holoparasite_user_roundend_stat", 1, info) SSblackbox.record_feedback("tally", "holoparasites_per_summoner", 1, length(members)) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index d5b08e4659ba3..5c20e4d4fe45a 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -374,7 +374,7 @@ if(SOFT_CRIT) data["occupant"]["stat"] = "Conscious" data["occupant"]["statstate"] = "average" - if(UNCONSCIOUS) + if(UNCONSCIOUS, HARD_CRIT) data["occupant"]["stat"] = "Unconscious" data["occupant"]["statstate"] = "average" if(DEAD) diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index 31581bd2fed07..2faed8d4b7e34 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -216,18 +216,19 @@ AddElement(/datum/element/point_of_interest) /obj/machinery/capture_the_flag/process(delta_time) - for(var/mob/living/M as() in spawned_mobs) - if(QDELETED(M)) - spawned_mobs -= M + for(var/mob/living/living_participant as anything in spawned_mobs) + if(QDELETED(living_participant)) + spawned_mobs -= living_participant continue // Anyone in crit, automatically reap - if(M.InCritical() || M.stat == DEAD) - ctf_dust_old(M) + + if(HAS_TRAIT(living_participant, TRAIT_CRITICAL_CONDITION) || living_participant.stat == DEAD) + ctf_dust_old(living_participant) else // The changes that you've been hit with no shield but not // instantly critted are low, but have some healing. - M.adjustBruteLoss(-2.5 * delta_time) - M.adjustFireLoss(-2.5 * delta_time) + living_participant.adjustBruteLoss(-2.5 * delta_time) + living_participant.adjustFireLoss(-2.5 * delta_time) /obj/machinery/capture_the_flag/red name = "Red CTF Controller" diff --git a/code/modules/awaymissions/mission_code/TheFactory.dm b/code/modules/awaymissions/mission_code/TheFactory.dm index c1bcc91e721fe..e9d250f822b1f 100644 --- a/code/modules/awaymissions/mission_code/TheFactory.dm +++ b/code/modules/awaymissions/mission_code/TheFactory.dm @@ -247,7 +247,7 @@ maxHealth = 100 health = 100 melee_damage = 12 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT faction = list("nanotrasenprivate") status_flags = CANPUSH atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) @@ -415,7 +415,7 @@ environment_smash = ENVIRONMENT_SMASH_NONE obj_damage = 5 sidestep_per_cycle = 0 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT melee_damage = 15 lose_patience_timeout = 350 loot = list(/obj/effect/mob_spawn/human/corpse/psychost) @@ -634,7 +634,7 @@ melee_damage = null attack_sound = null del_on_death = TRUE - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT a_intent = INTENT_HARM var/det_time = 30 var/active = 0 diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index 93e95ab50e35a..608e350ce5b4a 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -261,7 +261,7 @@ return TRUE if(SOFT_CRIT) to_chat(src, "You can't commit suicide while in a critical condition!") - if(UNCONSCIOUS) + if(UNCONSCIOUS, HARD_CRIT) to_chat(src, "You need to be conscious to commit suicide!") if(DEAD) to_chat(src, "You're already dead!") diff --git a/code/modules/client/verbs/who.dm b/code/modules/client/verbs/who.dm index e06e58bbae91c..31d19f3675415 100644 --- a/code/modules/client/verbs/who.dm +++ b/code/modules/client/verbs/who.dm @@ -20,7 +20,7 @@ else entry += " - Playing as [C.mob.real_name]" switch(C.mob.stat) - if(UNCONSCIOUS) + if(UNCONSCIOUS, HARD_CRIT) entry += " - Unconscious" if(DEAD) if(isobserver(C.mob)) diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index b12a30a257da9..8a92930af552c 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -7,13 +7,15 @@ /datum/round_event/heart_attack/start() var/list/heart_attack_contestants = list() - for(var/mob/living/carbon/human/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.diseases) || H.undergoing_cardiac_arrest()) + for(var/mob/living/carbon/human/victim in shuffle(GLOB.player_list)) + if(victim.stat == DEAD || HAS_TRAIT(victim, TRAIT_CRITICAL_CONDITION) || !victim.can_heartattack() || victim.has_status_effect(STATUS_EFFECT_EXERCISED) || (/datum/disease/heart_failure in victim.diseases) || victim.undergoing_cardiac_arrest()) continue - if(H.satiety <= -60) //Multiple junk food items recently - heart_attack_contestants[H] = 3 + if(!SSjob.GetJob(victim.mind.assigned_role) || (victim.mind.assigned_role in GLOB.nonhuman_positions))//only crewmembers can get one, a bit unfair for some ghost roles and it wastes the event + continue + if(victim.satiety <= -60) //Multiple junk food items recently + heart_attack_contestants[victim] = 3 else - heart_attack_contestants[H] = 1 + heart_attack_contestants[victim] = 1 if(LAZYLEN(heart_attack_contestants)) var/mob/living/carbon/human/winner = pick_weight(heart_attack_contestants) diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm index 43f1234dc833e..aac348eb79233 100644 --- a/code/modules/flufftext/Dreaming.dm +++ b/code/modules/flufftext/Dreaming.dm @@ -57,7 +57,7 @@ dream_sequence(dream_fragments) /mob/living/carbon/proc/dream_sequence(list/dream_fragments) - if(stat != UNCONSCIOUS || InCritical()) + if(stat != UNCONSCIOUS || HAS_TRAIT(src, TRAIT_CRITICAL_CONDITION)) dreaming = FALSE return var/next_message = dream_fragments[1] diff --git a/code/modules/holoparasite/_holoparasite.dm b/code/modules/holoparasite/_holoparasite.dm index 56c565aaaa0f2..99fdb77fbe344 100644 --- a/code/modules/holoparasite/_holoparasite.dm +++ b/code/modules/holoparasite/_holoparasite.dm @@ -187,7 +187,7 @@ GLOBAL_LIST_EMPTY_TYPED(holoparasites, /mob/living/simple_animal/hostile/holopar else health_percent = round((current.health / current.maxHealth) * 100, 0.5) var/stat_text = "[health_percent]%" - if(current.InCritical()) + if(HAS_TRAIT(current, TRAIT_CRITICAL_CONDITION)) stat_text += " (!! CRITICAL !!)" .["Summoner Health"] = GENERATE_STAT_TEXT(stat_text) if(!COOLDOWN_FINISHED(src, manifest_cooldown)) diff --git a/code/modules/holoparasite/holoparasite_damage.dm b/code/modules/holoparasite/holoparasite_damage.dm index f23b52f8e305a..4b273f893617a 100644 --- a/code/modules/holoparasite/holoparasite_damage.dm +++ b/code/modules/holoparasite/holoparasite_damage.dm @@ -85,7 +85,7 @@ */ /mob/living/simple_animal/hostile/holoparasite/proc/extra_host_damage(amount) // NOTE: checking unconscious and not sleeping here is intentional! ~Lucy - if(!summoner.current || !(summoner.current.IsUnconscious() || summoner.current.InCritical())) + if(!summoner.current || !(summoner.current.IsUnconscious() || HAS_TRAIT(summoner.current, TRAIT_CRITICAL_CONDITION))) return // No brain? Ah whatever, just deal clone damage. var/obj/item/organ/brain/brain = summoner.current.getorganslot(ORGAN_SLOT_BRAIN) diff --git a/code/modules/holoparasite/holoparasite_holder.dm b/code/modules/holoparasite/holoparasite_holder.dm index 34557a3455cf0..8b21df445d6c7 100644 --- a/code/modules/holoparasite/holoparasite_holder.dm +++ b/code/modules/holoparasite/holoparasite_holder.dm @@ -186,7 +186,7 @@ * * new_body: The slimeperson's new body. */ /datum/holoparasite_holder/proc/handle_slime_cheese(mob/living/carbon/human/old_body, mob/living/carbon/human/new_body) - if(!isslimeperson(old_body) || !isslimeperson(new_body) || (old_body.stat != DEAD && !old_body.InCritical())) + if(!isslimeperson(old_body) || !isslimeperson(new_body) || (old_body.stat != DEAD && !HAS_TRAIT(old_body, TRAIT_CRITICAL_CONDITION))) return var/datum/species/oozeling/slime/old_slime = old_body.dna.species var/datum/species/oozeling/slime/new_slime = new_body.dna.species diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index 5b4376a70e890..b21d8a356b2c1 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -12,7 +12,7 @@ else icon_state = "alien[caste]_dead" - else if((stat == UNCONSCIOUS && !asleep) || stat == SOFT_CRIT || IsParalyzed()) + else if((stat == UNCONSCIOUS && !asleep) || stat == HARD_CRIT || stat == SOFT_CRIT || IsParalyzed()) icon_state = "alien[caste]_unconscious" else if(leap_on_click) icon_state = "alien[caste]_pounce" diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index ae840004a3c39..3a5104e107302 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -639,7 +639,7 @@ severity = 9 if(-INFINITY to -95) severity = 10 - if(!InFullCritical()) + if(stat != HARD_CRIT) var/visionseverity = 4 switch(health) if(-8 to -4) @@ -755,13 +755,14 @@ if(health <= HEALTH_THRESHOLD_DEAD && !HAS_TRAIT(src, TRAIT_NODEATH)) death() return - if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT)) + if(health <= hardcrit_threshold && !HAS_TRAIT(src, TRAIT_NOHARDCRIT)) + set_stat(HARD_CRIT) + else if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT)) set_stat(UNCONSCIOUS) + else if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT)) + set_stat(SOFT_CRIT) else - if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT)) - set_stat(SOFT_CRIT) - else - set_stat(CONSCIOUS) + set_stat(CONSCIOUS) if(!is_blind()) var/datum/component/blind_sense/B = GetComponent(/datum/component/blind_sense) B?.RemoveComponent() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 8eca2fef03ea3..24adf825d4053 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -323,11 +323,11 @@ AdjustImmobilized(-60) set_resting(FALSE) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) /// Check ourselves to see if we've got any shrapnel, return true if we do. This is a much simpler version of what humans do, we only indicate we're checking ourselves if there's actually shrapnel /mob/living/carbon/proc/check_self_for_injuries() - if(stat == DEAD || stat == UNCONSCIOUS) + if(stat >= UNCONSCIOUS) return var/embeds = FALSE diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 8f1bde077b50f..6d1d236fa8e86 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -107,10 +107,11 @@ . += msg.Join("") if(!appears_dead) - if(stat == UNCONSCIOUS) - . += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep." - else if(InCritical()) - . += "[t_His] breathing is shallow and labored." + switch(stat) + if(SOFT_CRIT) + . += "[t_His] breathing is shallow and labored." + if(UNCONSCIOUS, HARD_CRIT) + . += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep." var/trait_exam = common_trait_examine() if(!isnull(trait_exam)) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index eb0afc831d983..aef1d2d2a2764 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -302,13 +302,14 @@ SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "religious_comfort", /datum/mood_event/religiously_comforted) if(!appears_dead) - if(stat == UNCONSCIOUS) - msg += "[t_He] [t_is]n't responding to anything around [t_him] and seem[p_s()] to be asleep.\n" - else - if(HAS_TRAIT(src, TRAIT_DUMB)) - msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" - if(InCritical()) + switch(stat) + if(UNCONSCIOUS, HARD_CRIT) + msg += "[t_He] [t_is]n't responding to anything around [t_him] and seem[p_s()] to be asleep.\n" + if(SOFT_CRIT) msg += "[t_He] [t_is] barely conscious.\n" + if(CONSCIOUS) + if(HAS_TRAIT(src, TRAIT_DUMB)) + msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" if(getorgan(/obj/item/organ/brain)) if(ai_controller?.ai_status == AI_STATUS_ON) msg += "[t_He] do[t_es]n't appear to be [t_him]self.\n" diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index ac50c774a2d12..9c0a3ac3f1c3d 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -701,7 +701,7 @@ ..() /mob/living/carbon/human/check_self_for_injuries() - if(stat == DEAD || stat == UNCONSCIOUS) + if(stat >= UNCONSCIOUS) return visible_message("[src] examines [p_them()]self.", \ diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 52e0b37c4cc8c..915675b096a9b 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -71,12 +71,12 @@ //They must be restrained, beheaded or gibbed to stop being a threat. if(regen_cooldown < world.time) var/heal_amt = heal_rate - if(C.InCritical()) + if(HAS_TRAIT(C, TRAIT_CRITICAL_CONDITION)) heal_amt *= 2 C.heal_overall_damage(heal_amt,heal_amt) C.adjustToxLoss(-heal_amt) C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -heal_amt) - if(!C.InCritical() && prob(4)) + if(!HAS_TRAIT(C, TRAIT_CRITICAL_CONDITION) && prob(4)) playsound(C, pick(spooks), 50, TRUE, 10) //Congrats you somehow died so hard you stopped being a zombie diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index 0d4013b78790e..b8a13c7e8eb9f 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -6,22 +6,43 @@ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_DEATHCOMA), PROC_REF(on_deathcoma_trait_gain)) RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_DEATHCOMA), PROC_REF(on_deathcoma_trait_loss)) + RegisterSignals(src, list( + SIGNAL_ADDTRAIT(TRAIT_CRITICAL_CONDITION), + SIGNAL_REMOVETRAIT(TRAIT_CRITICAL_CONDITION), + + SIGNAL_ADDTRAIT(TRAIT_NODEATH), + SIGNAL_REMOVETRAIT(TRAIT_NODEATH), + ), PROC_REF(update_succumb_action)) + ///Called when TRAIT_KNOCKEDOUT is added to the mob. /mob/living/proc/on_knockedout_trait_gain(datum/source) + SIGNAL_HANDLER if(stat < UNCONSCIOUS) set_stat(UNCONSCIOUS) ///Called when TRAIT_KNOCKEDOUT is removed from the mob. /mob/living/proc/on_knockedout_trait_loss(datum/source) - if(stat < DEAD) + SIGNAL_HANDLER + if(stat <= UNCONSCIOUS) update_stat() ///Called when TRAIT_DEATHCOMA is added to the mob. /mob/living/proc/on_deathcoma_trait_gain(datum/source) + SIGNAL_HANDLER ADD_TRAIT(src, TRAIT_KNOCKEDOUT, TRAIT_DEATHCOMA) ///Called when TRAIT_DEATHCOMA is removed from the mob. /mob/living/proc/on_deathcoma_trait_loss(datum/source) + SIGNAL_HANDLER REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, TRAIT_DEATHCOMA) + +/// Called when traits that alter succumbing are added/removed. +/// Will show or hide the succumb alert prompt. +/mob/living/proc/update_succumb_action() + SIGNAL_HANDLER + if (CAN_SUCCUMB(src)) + throw_alert("succumb", /atom/movable/screen/alert/succumb) + else + clear_alert("succumb") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 33ba095df18d7..b9f78997e3810 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -413,20 +413,23 @@ visible_message("[src] points at [A].", "You point at [A].") return TRUE + /mob/living/verb/succumb(whispered as null) set hidden = TRUE - if (InCritical()) - log_message("Has [whispered ? "whispered his final words" : "succumbed to death"] while in [InFullCritical() ? "hard":"soft"] critical with [round(health, 0.1)] points of health!", LOG_ATTACK) - adjustOxyLoss(health - HEALTH_THRESHOLD_DEAD) - updatehealth() - if(!whispered) - to_chat(src, "You have given up life and succumbed to death.") + if (!CAN_SUCCUMB(src)) + return + + log_message("Has [whispered ? "whispered his final words" : "succumbed to death"] with [round(health, 0.1)] points of health!", LOG_ATTACK) + adjustOxyLoss(health - HEALTH_THRESHOLD_DEAD) + updatehealth() + if(!whispered) + to_chat(src, "You have given up life and succumbed to death.") - if (src.client) - client.give_award(/datum/award/achievement/misc/succumb, client.mob) + if (src.client) + client.give_award(/datum/award/achievement/misc/succumb, client.mob) - investigate_log("has succumbed to death.", INVESTIGATE_DEATHS) - death() + investigate_log("has succumbed to death.", INVESTIGATE_DEATHS) + death() /mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_stasis = FALSE) if(stat || HAS_TRAIT(src, TRAIT_INCAPACITATED) || (!ignore_restraints && restrained(ignore_grab)) || (!ignore_stasis && IS_IN_STASIS(src))) @@ -437,12 +440,6 @@ return FALSE return TRUE -/mob/living/proc/InCritical() - return (health <= crit_threshold && (stat == SOFT_CRIT || stat == UNCONSCIOUS)) - -/mob/living/proc/InFullCritical() - return (health <= HEALTH_THRESHOLD_FULLCRIT && stat == UNCONSCIOUS) - //This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually //affects them once clothing is factored in. ~Errorage /mob/living/proc/calculate_affecting_pressure(pressure) @@ -1330,19 +1327,36 @@ if(pulledby) REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) if(UNCONSCIOUS) - cure_blind(UNCONSCIOUS_TRAIT) + if(stat != HARD_CRIT) + cure_blind(UNCONSCIOUS_TRAIT) + if(HARD_CRIT) + if(stat != UNCONSCIOUS) + cure_blind(UNCONSCIOUS_TRAIT) switch(stat) //Current stat. if(CONSCIOUS) if(. >= UNCONSCIOUS) REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) REMOVE_TRAIT(src, TRAIT_FLOORED, UNCONSCIOUS_TRAIT) + REMOVE_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT) if(SOFT_CRIT) if(pulledby) ADD_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) //adding trait sources should come before removing to avoid unnecessary updates if(. >= UNCONSCIOUS) REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) + ADD_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT) if(UNCONSCIOUS) - become_blind(UNCONSCIOUS_TRAIT) + if(. != HARD_CRIT) + become_blind(UNCONSCIOUS_TRAIT) + if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT)) + ADD_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT) + else + REMOVE_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT) + if(HARD_CRIT) + if(. != UNCONSCIOUS) + become_blind(UNCONSCIOUS_TRAIT) + ADD_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT) + if(DEAD) + REMOVE_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT) ///Reports the event of the change in value of the buckled variable. /mob/living/proc/set_buckled(new_buckled) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 082e4fe7fe260..87de7f252b1de 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -75,8 +75,6 @@ GLOBAL_LIST_INIT(department_radio_keys, list( return new_msg /mob/living/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language, ignore_spam = FALSE, forced) - var/static/list/crit_allowed_modes = list(WHISPER_MODE = TRUE, MODE_ALIEN = TRUE) - var/static/list/unconscious_allowed_modes = list(MODE_ALIEN = TRUE) var/ic_blocked = FALSE if(client && !forced && CHAT_FILTER_CHECK(message)) @@ -99,16 +97,24 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/original_message = message message = get_message_mods(message, message_mods) var/datum/saymode/saymode = SSradio.saymodes[message_mods[RADIO_KEY]] - var/in_critical = InCritical() if(!message) return message = check_for_custom_say_emote(message, message_mods) - if(stat == DEAD) - say_dead(original_message) - return + switch(stat) + if(SOFT_CRIT) + message_mods[WHISPER_MODE] = MODE_WHISPER + if(UNCONSCIOUS) + if(!(message_mods[MODE_ALIEN])) + return + if(HARD_CRIT) + if(!(message_mods[WHISPER_MODE] || message_mods[MODE_ALIEN])) + return + if(DEAD) + say_dead(original_message) + return if(saymode && saymode.early && !saymode.handle_message(src, message, language)) return @@ -116,23 +122,6 @@ GLOBAL_LIST_INIT(department_radio_keys, list( if(is_muted(original_message, ignore_spam, forced) || check_emote(original_message, forced)) return - if(in_critical) //There are cheaper ways to do this, but they're less flexible, and this isn't ran all that often - var/end = TRUE - for(var/index in message_mods) - if(crit_allowed_modes[index]) - end = FALSE - break - if(end) - return - else if(stat == UNCONSCIOUS) - var/end = TRUE - for(var/index in message_mods) - if(unconscious_allowed_modes[index]) - end = FALSE - break - if(end) - return - if(!language) // get_message_mods() proc finds a language key, and add the language to LANGUAGE_EXTENSION language = message_mods[LANGUAGE_EXTENSION] @@ -155,15 +144,12 @@ GLOBAL_LIST_INIT(department_radio_keys, list( log_message(message_mods[MODE_CUSTOM_SAY_EMOTE], LOG_RADIO_EMOTE) if(!message_mods[MODE_CUSTOM_SAY_ERASE_INPUT]) - var/fullcrit = InFullCritical() - if((in_critical && !fullcrit) || message_mods[WHISPER_MODE] == MODE_WHISPER) + if(message_mods[WHISPER_MODE] == MODE_WHISPER) if(saymode || message_mods[RADIO_EXTENSION]) //no radio while in crit saymode = null message_mods -= RADIO_EXTENSION message_range = 1 - message_mods[WHISPER_MODE] = MODE_WHISPER - log_talk(message, LOG_WHISPER, custom_say_emote = message_mods[MODE_CUSTOM_SAY_EMOTE]) - if(fullcrit) + if(stat == HARD_CRIT) var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health) // If we cut our message short, abruptly end it with a-.. var/message_len = length_char(message) diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 2ea45213c9758..2ddcbde6fe95d 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -76,7 +76,7 @@ if(health <= HEALTH_THRESHOLD_DEAD) death() return - else if(stat == UNCONSCIOUS) + else if(stat >= UNCONSCIOUS) set_stat(CONSCIOUS) diag_hud_set_status() diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index c206591f427ad..d05061352dbf7 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -39,7 +39,7 @@ . += "It appears to be an [deployed ? "active" : "empty"] AI shell." else if(!client) . += "It appears to be in stand-by mode." //afk - if(UNCONSCIOUS) + if(SOFT_CRIT, UNCONSCIOUS, HARD_CRIT) . += "It doesn't seem to be responding." if(DEAD) . += "It looks like its system is corrupted and requires a reset." diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index a14b8be87f8c5..067c92f2898cf 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -238,7 +238,7 @@ var/refund = 0 if(QDELETED(L) || (L.stat == DEAD && prev_stat != DEAD)) //they're dead, you killed them refund += kill_refund - else if(L.InCritical() && prev_stat == CONSCIOUS) //you knocked them into critical + else if(HAS_TRAIT(L, TRAIT_CRITICAL_CONDITION) && prev_stat == CONSCIOUS) //you knocked them into critical refund += crit_refund if(L.stat != DEAD && prev_stat != DEAD) refund += attack_refund diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm index 4f0a1fe6a3c62..8eb1c7212184e 100644 --- a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm +++ b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm @@ -2,7 +2,7 @@ name = "\improper A Perfectly Generic Boss Placeholder" desc = "" robust_searching = 1 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT status_flags = 0 a_intent = INTENT_HARM gender = NEUTER diff --git a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm index d03eab4ca56f9..a8a5d7da1a4de 100644 --- a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm +++ b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm @@ -18,7 +18,7 @@ response_disarm = "shoves" response_harm = "hits" speed = 0 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 maxHealth = 100 health = 100 diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index 57e42b4c74709..6688fde07d651 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -17,7 +17,7 @@ maxHealth = 80 health = 80 spacewalk = TRUE - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 obj_damage = 50 diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm index 85ca2b882c0c7..6661246c29a48 100644 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm +++ b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm @@ -30,7 +30,7 @@ possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM) faction = list("jungle") robust_searching = TRUE - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT minbodytemp = 270 maxbodytemp = 350 unique_name = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/heart.dm b/code/modules/mob/living/simple_animal/hostile/heart.dm index 7ca09c012a641..f955d20acdfad 100644 --- a/code/modules/mob/living/simple_animal/hostile/heart.dm +++ b/code/modules/mob/living/simple_animal/hostile/heart.dm @@ -21,7 +21,7 @@ attacktext = "beats" ventcrawler = VENTCRAWLER_ALWAYS attack_sound = 'sound/effects/singlebeat.ogg' - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT attack_same = 1 gold_core_spawnable = HOSTILE_SPAWN see_in_dark = 8 diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 3273d02408ac6..c4adc619b768c 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -43,7 +43,8 @@ var/search_objects_timer_id //Timer for regaining our old search_objects value after being attacked var/search_objects_regain_time = 30 //the delay between being attacked and gaining our old search_objects value back var/list/wanted_objects = list() //A typecache of objects types that will be checked against to attack, should we have search_objects enabled - var/stat_attack = CONSCIOUS //Mobs with stat_attack to UNCONSCIOUS will attempt to attack things that are unconscious, Mobs with stat_attack set to DEAD will attempt to attack the dead. + ///Mobs ignore mob/living targets with a stat lower than that of stat_attack. If set to DEAD, then they'll include corpses in their targets, if to HARD_CRIT they'll keep attacking until they kill, and so on. + var/stat_attack = CONSCIOUS var/stat_exclusive = FALSE //Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack DEAD means they will only attack corpses var/attack_same = 0 //Set us to 1 to allow us to attack our own faction //Use GET_TARGETS_FROM(mob) to access this diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index e6a64102c6fad..e12c6e9011f98 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -21,7 +21,7 @@ base_pixel_x = -16 layer = LARGE_MOB_LAYER speed = 10 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 var/hopping = FALSE var/hop_cooldown = 0 //Strictly for player controlled leapers diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm index 8b50d7fc54656..514ebf22504a2 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm @@ -22,7 +22,7 @@ ranged_cooldown_time = 10 pass_flags_self = LETPASSTHROW robust_searching = TRUE - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT attack_sound = 'sound/weapons/rapierhit.ogg' deathsound = 'sound/voice/mook_death.ogg' aggro_vision_range = 15 //A little more aggressive once in combat to balance out their really low HP diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm index fd1922dd89049..e21457265a009 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm @@ -26,7 +26,7 @@ projectiletype = /obj/projectile/seedling projectilesound = 'sound/weapons/pierce.ogg' robust_searching = TRUE - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT move_resist = MOVE_FORCE_EXTREMELY_STRONG var/combatant_state = SEEDLING_STATE_NEUTRAL var/obj/seedling_weakpoint/weak_point diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 3c6869f664992..7184569458639 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -105,11 +105,13 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/legion/AttackingTarget() . = ..() - if(. && ishuman(target)) - var/mob/living/L = target - if(L.stat == UNCONSCIOUS) - var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new(loc) - A.infest(L) + if(!. || !ishuman(target)) + return + var/mob/living/living_target = target + switch(living_target.stat) + if(UNCONSCIOUS, HARD_CRIT) + var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/legion = new(loc) + legion.infest(living_target) /mob/living/simple_animal/hostile/megafauna/legion/proc/reset_charge() ranged = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index 3356538ca7c31..90b948f3e0d15 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -15,7 +15,7 @@ movement_type = FLYING robust_searching = TRUE ranged_ignores_vision = TRUE - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) minbodytemp = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 44af7d8b8b987..ba1a973306c90 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -76,7 +76,7 @@ a_intent = INTENT_HARM speak_emote = list("telepathically cries") attack_sound = 'sound/weapons/bladeslice.ogg' - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT movement_type = FLYING robust_searching = 1 crusher_loot = /obj/item/crusher_trophy/watcher_wing diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm index ed14b01ad5f84..4766f9269d10b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm @@ -15,7 +15,7 @@ vision_range = 6 aggro_vision_range = 18 environment_smash = ENVIRONMENT_SMASH_NONE //This is to prevent elites smashing up the mining station, we'll make sure they can smash minerals fine below. - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT layer = LARGE_MOB_LAYER sentience_type = SENTIENCE_BOSS hud_type = /datum/hud/lavaland_elite diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index 3dce29204e2a8..dd7f054f8be9f 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -95,7 +95,7 @@ butcher_results = list(/obj/item/food/meat/slab/goliath = 2, /obj/item/stack/sheet/bone = 2) guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide = 1) loot = list() - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 /mob/living/simple_animal/hostile/asteroid/goliath/beast/random/Initialize(mapload) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm index c87121b9e2933..e65cbd6ee616b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm @@ -25,7 +25,7 @@ a_intent = INTENT_HELP ventcrawler = VENTCRAWLER_ALWAYS gold_core_spawnable = FRIENDLY_SPAWN - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT gender = NEUTER stop_automated_movement = FALSE stop_automated_movement_when_pulled = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index c9cfd437ab0b3..96f45457005f6 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -107,7 +107,7 @@ loot = list(/obj/item/organ/regenerative_core/legion) brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion del_on_death = TRUE - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 var/dwarf_mob = FALSE var/mob/living/carbon/human/stored_mob @@ -170,16 +170,24 @@ throw_message = "is shrugged off by" pass_flags = PASSTABLE del_on_death = TRUE - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 var/can_infest_dead = FALSE /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life() - if(isturf(loc)) - for(var/mob/living/carbon/human/H in viewers(1, src)) //Only for corpse right next to/on same tile - if(H.stat == UNCONSCIOUS || (can_infest_dead && H.stat == DEAD)) - infest(H) - ..() + . = ..() + if(stat == DEAD || !isturf(loc)) + return + + for(var/mob/living/carbon/human/victim in viewers(1, src)) //Only for corpse right next to/on same tile + switch(victim.stat) + if(UNCONSCIOUS, HARD_CRIT) + infest(victim) + return //This will qdelete the legion. + if(DEAD) + if(can_infest_dead) + infest(victim) + return //This will qdelete the legion. /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/proc/infest(mob/living/carbon/human/H) visible_message("[name] burrows into the flesh of [H]!") diff --git a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm index 33a2109927b93..b3b02061b6366 100644 --- a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm +++ b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm @@ -13,7 +13,7 @@ response_disarm = "shoves" response_harm = "hits" speed = 0 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 maxHealth = 100 health = 100 diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index d7742984d65a9..d36021d7a6fec 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -231,7 +231,7 @@ speed = 5 melee_damage = 30 armour_penetration = 30 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT attacktext = "acts out divine vengeance on" obj_damage = 50 environment_smash = ENVIRONMENT_SMASH_RWALLS diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm index 658cd5701d00c..1ffe61a4a9514 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm @@ -36,7 +36,7 @@ response_disarm = "shoves" response_harm = "hits" speed = 0 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 vision_range = 3 maxHealth = 100 diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm index b59a33cddc592..ddb56921b76f2 100644 --- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -23,7 +23,7 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 10 robust_searching = 1 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT gold_core_spawnable = HOSTILE_SPAWN faction = list("skeleton") see_in_dark = 8 diff --git a/code/modules/mob/living/simple_animal/hostile/stickman.dm b/code/modules/mob/living/simple_animal/hostile/stickman.dm index 288d069bebd8c..2b9bf5c926728 100644 --- a/code/modules/mob/living/simple_animal/hostile/stickman.dm +++ b/code/modules/mob/living/simple_animal/hostile/stickman.dm @@ -13,7 +13,7 @@ response_disarm = "shoves" response_harm = "hits" speed = 0 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 environment_smash = ENVIRONMENT_SMASH_NONE maxHealth = 100 diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 4716c1d72bc04..b3c458a614054 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -29,7 +29,7 @@ response_disarm = "shoves" response_harm = "hits" speed = 0 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 maxHealth = 100 health = 100 diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/zombie.dm index e446b65169bb3..217750b056447 100644 --- a/code/modules/mob/living/simple_animal/hostile/zombie.dm +++ b/code/modules/mob/living/simple_animal/hostile/zombie.dm @@ -6,7 +6,7 @@ icon_living = "zombie" mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID) speak_chance = 0 - stat_attack = UNCONSCIOUS //braains + stat_attack = HARD_CRIT //braains maxHealth = 100 health = 100 melee_damage = 21 diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index ec700c523c358..7eb8018945080 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -26,11 +26,13 @@ handle_mood() handle_speech() -// Unlike most of the simple animals, slimes support UNCONSCIOUS +// Unlike most of the simple animals, slimes support UNCONSCIOUS. This is an ugly hack. /mob/living/simple_animal/slime/update_stat() - if(stat == UNCONSCIOUS && health > 0) - return - ..() + switch(stat) + if(UNCONSCIOUS, HARD_CRIT) + if(health > 0) + return + return ..() /mob/living/simple_animal/slime/process() if(stat == DEAD || !Target || client || buckled) @@ -101,18 +103,21 @@ environment.adjust_moles(GAS_O2, plas_amt) adjustBruteLoss(plas_amt ? -2 : 0) - if(stat == CONSCIOUS && stasis) - to_chat(src, "Nerve gas in the air has put you in stasis!") - set_stat(UNCONSCIOUS) - powerlevel = 0 - rabid = 0 - update_mobility() - regenerate_icons() - else if(stat == UNCONSCIOUS && !stasis) - to_chat(src, "You wake up from the stasis.") - set_stat(CONSCIOUS) - update_mobility() - regenerate_icons() + switch(stat) + if(CONSCIOUS) + if(stasis) + to_chat(src, "Nerve gas in the air has put you in stasis!") + set_stat(UNCONSCIOUS) + powerlevel = 0 + rabid = FALSE + update_mobility() + regenerate_icons() + if(UNCONSCIOUS, HARD_CRIT) + if(!stasis) + to_chat(src, "You wake up from the stasis.") + set_stat(CONSCIOUS) + update_mobility() + regenerate_icons() updatehealth() diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index cbbb9c3b539c8..651a7b3cf3ea9 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -250,10 +250,11 @@ else tab_data["Slime Status"] = GENERATE_STAT_TEXT("You can evolve!") - if(stat == UNCONSCIOUS) - tab_data["Unconscious"] = GENERATE_STAT_TEXT("You are knocked out by high levels of BZ!") - else - tab_data["Power Level"] = GENERATE_STAT_TEXT("[powerlevel]") + switch(stat) + if(HARD_CRIT, UNCONSCIOUS) + tab_data["Unconscious"] = GENERATE_STAT_TEXT("You are knocked out by high levels of BZ!") + else + tab_data["Power Level"] = GENERATE_STAT_TEXT("[powerlevel]") return tab_data /mob/living/simple_animal/slime/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) @@ -453,7 +454,7 @@ if (stat == DEAD) . += "It is limp and unresponsive." else - if (stat == UNCONSCIOUS) // Slime stasis + if (stat == UNCONSCIOUS || stat == HARD_CRIT) // Slime stasis . += "It appears to be alive but unresponsive." if (getBruteLoss()) . += "" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 67be1d596f061..1b60348ca4ba4 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -177,7 +177,7 @@ if(type & MSG_VISUAL && is_blind()) return // voice muffling - if(stat == UNCONSCIOUS) + if(stat == UNCONSCIOUS || stat == HARD_CRIT) if(type & MSG_AUDIBLE) //audio to_chat(src, "... You can almost hear something ...") return @@ -807,7 +807,7 @@ /mob/proc/canface() if(world.time < client.last_turn) return FALSE - if(stat == DEAD || stat == UNCONSCIOUS) + if(stat >= UNCONSCIOUS) return FALSE if(anchored) return FALSE diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index df83a10c1cb70..ba8365c964a17 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -46,22 +46,34 @@ update_blindness() /// proc that adds and removes blindness overlays when necessary -/mob/proc/update_blindness(overlay = /atom/movable/screen/fullscreen/blind, add_color = TRUE, var/can_see = TRUE) - if(stat == UNCONSCIOUS || HAS_TRAIT(src, TRAIT_BLIND) || eye_blind) // UNCONSCIOUS or has blind trait, or has temporary blindness - if((stat == CONSCIOUS || stat == SOFT_CRIT) && istype(overlay, /atom/movable/screen/alert)) - throw_alert("blind", overlay) - overlay_fullscreen("blind", overlay) +/mob/proc/update_blindness(overlay = /atom/movable/screen/fullscreen/blind, add_color = TRUE, can_see = TRUE) + switch(stat) + if(CONSCIOUS, SOFT_CRIT) + if(HAS_TRAIT(src, TRAIT_BLIND) || eye_blind && istype(overlay, /atom/movable/screen/alert)) + throw_alert("blind", /atom/movable/screen/alert/blind) + do_set_blindness(FALSE, overlay, add_color) + else + do_set_blindness(TRUE, overlay, add_color) + if(UNCONSCIOUS, HARD_CRIT) + do_set_blindness(FALSE, overlay, add_color) + if(DEAD) + do_set_blindness(TRUE, overlay, add_color) + +///Proc that handles adding and removing the blindness overlays. +/mob/proc/do_set_blindness(can_see, overlay_setter, add_color_setter) + if(!can_see) + overlay_fullscreen("blind", overlay_setter) // You are blind why should you be able to make out details like color, only shapes near you - if(add_color) + if(add_color_setter) add_client_colour(/datum/client_colour/monochrome/blind) - var/datum/component/blind_sense/B = GetComponent(/datum/component/blind_sense) + var/datum/component/blind_sense/B = GetComponent(/datum/component/blind_sense) if(!B && !QDELING(src) && !QDELETED(src)) AddComponent(/datum/component/blind_sense) - else if(can_see) // CONSCIOUS no blind trait, no blindness + else clear_alert("blind") clear_fullscreen("blind") remove_client_colour(/datum/client_colour/monochrome/blind) - var/datum/component/blind_sense/B = GetComponent(/datum/component/blind_sense) + var/datum/component/blind_sense/B = GetComponent(/datum/component/blind_sense) B?.RemoveComponent() /** diff --git a/code/modules/research/nanites/nanite_programs/sensor.dm b/code/modules/research/nanites/nanite_programs/sensor.dm index dfbecbfb451bb..5ecd5b43a2ac8 100644 --- a/code/modules/research/nanites/nanite_programs/sensor.dm +++ b/code/modules/research/nanites/nanite_programs/sensor.dm @@ -110,14 +110,13 @@ var/spent = FALSE /datum/nanite_program/sensor/crit/check_event() - if(host_mob.InCritical()) - if(!spent) - spent = TRUE - return TRUE - return FALSE - else - spent = FALSE - return FALSE + if(HAS_TRAIT(host_mob, TRAIT_CRITICAL_CONDITION)) + if(spent) + return FALSE + spent = TRUE + return TRUE + spent = FALSE + return FALSE /datum/nanite_program/sensor/crit/make_rule(datum/nanite_program/target) var/datum/nanite_rule/crit/rule = new(target) diff --git a/code/modules/research/nanites/rules.dm b/code/modules/research/nanites/rules.dm index 34903a9b30d44..974e9c8d930c0 100644 --- a/code/modules/research/nanites/rules.dm +++ b/code/modules/research/nanites/rules.dm @@ -55,9 +55,7 @@ desc = "Checks if the host is in critical condition." /datum/nanite_rule/crit/check_rule() - if(program.host_mob.InCritical()) - return TRUE - return FALSE + return HAS_TRAIT(program.host_mob, TRAIT_CRITICAL_CONDITION) /datum/nanite_rule/death name = "Death" diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index 0189c0810d00d..7a8926d6130fc 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -489,7 +489,7 @@ var/obj/item/cavity_item /obj/item/bodypart/chest/can_dismember(obj/item/I) - if(!((owner.stat == DEAD) || owner.InFullCritical())) + if(owner.stat < HARD_CRIT) return FALSE return ..() diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 86deb37be5a1c..56a1fc0f1346a 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -60,7 +60,6 @@ if(HAS_TRAIT(C, TRAIT_NODISMEMBER)) return FALSE . = list() - var/organ_spilled = 0 var/turf/T = get_turf(C) C.add_splatter_floor(T) playsound(get_turf(C), 'sound/misc/splort.ogg', 80, 1) @@ -71,18 +70,11 @@ continue O.Remove(C) O.forceMove(T) - organ_spilled = 1 . += X if(cavity_item) cavity_item.forceMove(T) . += cavity_item cavity_item = null - organ_spilled = 1 - - if(organ_spilled) - C.visible_message("[C]'s internal organs spill out onto the floor!") - - //limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in. /obj/item/bodypart/proc/drop_limb(special, dismembered) diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 470ef9dd89132..dfea115b83e7b 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -94,7 +94,7 @@ /obj/item/bodypart/head/can_dismember(obj/item/I) - if(!((owner.stat == DEAD) || owner.InFullCritical())) + if(owner.stat < HARD_CRIT) return FALSE return ..() diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 588b64fece84b..eca93f0723ede 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -51,29 +51,28 @@ implant_color = "#AD0000" slot = ORGAN_SLOT_HEART_AID var/revive_cost = 0 - var/reviving = 0 - var/cooldown = 0 + var/reviving = FALSE + COOLDOWN_DECLARE(reviver_cooldown) /obj/item/organ/cyberimp/chest/reviver/on_life() if(reviving) - if(owner.stat) - addtimer(CALLBACK(src, PROC_REF(heal)), 30) - else - cooldown = revive_cost + world.time - reviving = FALSE - to_chat(owner, "Your reviver implant shuts down and starts recharging. It will be ready again in [DisplayTimeText(revive_cost)].") + switch(owner.stat) + if(UNCONSCIOUS, HARD_CRIT) + addtimer(CALLBACK(src, PROC_REF(heal)), 30) + else + COOLDOWN_START(src, reviver_cooldown, revive_cost) + reviving = FALSE + to_chat(owner, "Your reviver implant shuts down and starts recharging. It will be ready again in [DisplayTimeText(revive_cost)].") return - if(cooldown > world.time) - return - if(!owner.stat) - return - if(owner.suiciding) + if(!COOLDOWN_FINISHED(src, reviver_cooldown) || owner.suiciding) return - revive_cost = 0 - reviving = TRUE - to_chat(owner, "You feel a faint buzzing as your reviver implant starts patching your wounds...") + switch(owner.stat) + if(UNCONSCIOUS, HARD_CRIT) + revive_cost = 0 + reviving = TRUE + to_chat(owner, "You feel a faint buzzing as your reviver implant starts patching your wounds...") /obj/item/organ/cyberimp/chest/reviver/proc/heal() if(owner.getOxyLoss()) @@ -97,7 +96,7 @@ if(reviving) revive_cost += 200 else - cooldown += 200 + reviver_cooldown += 20 SECONDS if(ishuman(owner)) var/mob/living/carbon/human/H = owner diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index 76c07e66b9712..4c71ed24455b1 100644 Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ