diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index a77b65acf81..10a6ab98c5c 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 080559a25f7..3eb8c2f6ed5 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -80,6 +80,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_IMMOBILIZED "immobilized" //Prevents voluntary movement. #define TRAIT_FLOORED "floored" //Prevents standing or staying up on its own. #define TRAIT_INCAPACITATED "incapacitated" +#define TRAIT_CRITICAL_CONDITION "critical-condition" //In some kind of critical condition. Is able to succumb. #define TRAIT_BLIND "blind" #define TRAIT_MUTE "mute" #define TRAIT_EMOTEMUTE "emotemute" @@ -279,6 +280,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define BUCKLED_TRAIT "buckled" //trait associated to being buckled #define CHOKEHOLD_TRAIT "chokehold" //trait associated to being held in a chokehold #define RESTING_TRAIT "resting" //trait associated to resting +#define STAT_TRAIT "stat" //trait associated to a stat value or range of // unique trait sources, still defines #define CLONING_POD_TRAIT "cloning-pod" diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 245fb4e7e40..a049288947c 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -269,10 +269,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) to_chat(M, "You feel yourself slip into a regenerative coma...") active_coma = TRUE diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index d0f37526174..19575faa0f4 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -134,7 +134,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/datums/mutations/body.dm b/code/datums/mutations/body.dm index e3e015802ef..1cf14fd205c 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -435,7 +435,7 @@ /datum/mutation/human/martyrdom/proc/bloody_shower(new_stat) SIGNAL_HANDLER - if(new_stat != UNCONSCIOUS) + if(new_stat != HARD_CRIT) return var/list/organs = owner.getorganszone(BODY_ZONE_HEAD, 1) diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 3863fcc991e..0044d18f106 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -338,7 +338,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 e0852a7e9c8..3c65135dbe4 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -498,7 +498,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/Sleeper.dm b/code/game/machinery/Sleeper.dm index 19cfd3c10b7..582fdb39916 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -185,7 +185,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/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 8942f83e535..619360c8104 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -104,7 +104,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 72c2c5a935a..e3e8c548fe3 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -92,7 +92,7 @@ switch (occupier.stat) if (CONSCIOUS) . += "ai-fixer-full" - if (UNCONSCIOUS) + if (UNCONSCIOUS, HARD_CRIT) . += "ai-fixer-404" else . += "ai-fixer-empty" diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 2825af993c5..2f2418150d4 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -752,7 +752,7 @@ GLOBAL_LIST_EMPTY(PDAs) else L = get(src, /mob/living/silicon) - if(L && L.stat != UNCONSCIOUS) + if(L && (L.stat == CONSCIOUS || L.stat == SOFT_CRIT)) var/reply = "(Reply)" var/hrefstart var/hrefend diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 7c3ba200bd3..0135d1f9bd5 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1282,7 +1282,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/distributed_neurons.dm b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm index 3581a5e8501..513b87c3725 100644 --- a/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm +++ b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm @@ -27,7 +27,7 @@ /datum/reagent/blob/distributed_neurons/expose_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.death() //sleeping in a fight? bad plan. var/points = rand(5, 10) var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M)) diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index 5385636a08d..c03f817b43e 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 c586e35d5a0..5428d4a34a5 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 = 20 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 1098f541635..5ba9410eaa5 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 a060cda7f8e..a87a41e2bbc 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 = 0 - 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 6c318070f2c..f3865f348df 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -816,7 +816,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/eldritch_cult/eldritch_magic.dm b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm index 22b1b4a8b16..f6cdbbc9ebf 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm @@ -510,7 +510,7 @@ if(target.stat == DEAD || !target.on_fire) continue //This is essentially a death mark, use this to finish your opponent quicker. - if(target.InCritical()) + if(HAS_TRAIT(target, TRAIT_CRITICAL_CONDITION)) target.death() target.adjustFireLoss(20) new /obj/effect/temp_visual/eldritch_smoke(target.drop_location()) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index b0e04976a97..e7c34ac9652 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -391,7 +391,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 cf89a0b7293..8937e7f0616 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -181,14 +181,15 @@ spawned_mobs -= i continue // Anyone in crit, automatically reap - var/mob/living/M = i - if(M.InCritical() || M.stat == DEAD) - ctf_dust_old(M) + var/mob/living/living_participant = i + 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(-5) - M.adjustFireLoss(-5) + living_participant.adjustBruteLoss(-5) + living_participant.adjustFireLoss(-5) + /obj/machinery/capture_the_flag/red name = "Red CTF Controller" diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index b9c60c25843..625e448c5d0 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -250,7 +250,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 f1587b78109..55ddadcd0dd 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/fake_virus.dm b/code/modules/events/fake_virus.dm index 61a965df3b2..e2a68a937d7 100644 --- a/code/modules/events/fake_virus.dm +++ b/code/modules/events/fake_virus.dm @@ -5,10 +5,10 @@ /datum/round_event/fake_virus/start() var/list/fake_virus_victims = list() - for(var/mob/living/carbon/human/H in shuffle(GLOB.player_list)) - if(!H.client || H.stat == DEAD || H.InCritical() || (!SSjob.GetJob(H.mind.assigned_role) || (H.mind.assigned_role in GLOB.nonhuman_positions))) + for(var/mob/living/carbon/human/victim in shuffle(GLOB.player_list)) + if(victim.stat == DEAD || HAS_TRAIT(victim, TRAIT_CRITICAL_CONDITION) || !SSjob.GetJob(victim.mind.assigned_role) || (victim.mind.assigned_role in GLOB.nonhuman_positions)) continue - fake_virus_victims += H + fake_virus_victims += victim //first we do hard status effect victims var/defacto_min = min(3, LAZYLEN(fake_virus_victims)) diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index eac3a03a133..fc4b660d5cb 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -7,15 +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(!SSjob.GetJob(H.mind.assigned_role) || (H.mind.assigned_role in GLOB.nonhuman_positions))//only crewmembers can get one, a bit unfair for some ghost roles and it wastes the event + 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(H.satiety <= -60) //Multiple junk food items recently - heart_attack_contestants[H] = 3 + 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 = pickweight(heart_attack_contestants) diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm index 43c3337a4b3..4b1e181d656 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/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm index 1d0842b5f7a..6ca74172a48 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/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 61ae8acf204..962aba1073c 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -681,7 +681,7 @@ severity = 9 if(-INFINITY to -95) severity = 10 - if(!InFullCritical()) + if(stat != HARD_CRIT) var/visionseverity = 4 switch(health) if(-8 to -4) @@ -804,18 +804,20 @@ 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) update_mobility() update_damage_hud() update_health_hud() med_hud_set_status() + //called when we get cuffed/uncuffed /mob/living/carbon/proc/update_handcuffed() if(handcuffed) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 4402b9ea2eb..2ea7700ca74 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -480,7 +480,7 @@ /// 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 12ecaffcd3f..b6d8bb0cd0a 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -125,10 +125,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 1a17d1d0603..73de1719463 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -339,13 +339,14 @@ msg += "[t_He] [t_has] a holy aura about [t_him].\n" SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "religious_comfort", /datum/mood_event/religiously_comforted) - 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(!key) msg += "[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.\n" diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 046fb020acd..13c8f37e926 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -694,7 +694,7 @@ check_self_for_injuries() /mob/living/carbon/human/check_self_for_injuries() - if(stat == DEAD || stat == UNCONSCIOUS) + if(stat >= UNCONSCIOUS) return var/list/combined_msg = list() 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 5e4ec8b810f..a2b3d7e2dbe 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -59,7 +59,7 @@ //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) @@ -67,7 +67,7 @@ var/datum/wound/iter_wound = i if(prob(4-iter_wound.severity)) iter_wound.remove_wound() - 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 4b5cc7989f5..d3301d638d6 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -14,7 +14,7 @@ ///Called when TRAIT_KNOCKEDOUT is removed from the mob. /mob/living/proc/on_knockedout_trait_loss(datum/source) - if(stat < DEAD) + if(stat <= UNCONSCIOUS) update_stat() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bae1267cdd2..761a331edca 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -381,15 +381,18 @@ visible_message("[src] points at [A].", "You point at [A].") return TRUE + /mob/living/verb/succumb(whispered as null) set hidden = TRUE - if (InCritical() && !HAS_TRAIT(src, TRAIT_NODEATH)) - 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.") - death() + if (!HAS_TRAIT(src, TRAIT_CRITICAL_CONDITION) || HAS_TRAIT(src, TRAIT_NODEATH)) + 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.") + 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))) @@ -400,11 +403,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 @@ -1641,19 +1639,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. diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index ce4043c59c9..a20a5d3c354 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -82,9 +82,6 @@ GLOBAL_LIST_INIT(department_radio_keys, list( return new_msg /mob/living/say(message, bubble_type,list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) - var/static/list/crit_allowed_modes = list(WHISPER_MODE = TRUE, MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE) - var/static/list/unconscious_allowed_modes = list(MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE) - var/ic_blocked = FALSE if(client && !forced && CHAT_FILTER_CHECK(message)) //The filter doesn't act on the sanitized message, but the raw message. @@ -104,45 +101,34 @@ 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 + if(message_mods[RADIO_EXTENSION] == MODE_ADMIN) - if(client) - client.cmd_admin_say(message) + client?.cmd_admin_say(message) return if(message_mods[RADIO_EXTENSION] == MODE_DEADMIN) - if(client) - client.dsay(message) + client?.dsay(message) return - 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_CHANGELING] || message_mods[MODE_ALIEN])) + return + if(HARD_CRIT) + if(!(message_mods[WHISPER_MODE] || message_mods[MODE_CHANGELING] || message_mods[MODE_ALIEN])) + return + if(DEAD) + say_dead(original_message) + return if(check_emote(original_message, forced) || !can_speak_basic(original_message, ignore_spam, 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 - - language = message_mods[LANGUAGE_EXTENSION] if(!language) @@ -156,12 +142,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/succumbed = FALSE - var/fullcrit = InFullCritical() - if((InCritical() && !fullcrit) || message_mods[WHISPER_MODE] == MODE_WHISPER) + if(message_mods[WHISPER_MODE] == MODE_WHISPER) message_range = 1 - message_mods[WHISPER_MODE] = MODE_WHISPER - src.log_talk(message, LOG_WHISPER) - if(fullcrit) + log_talk(message, LOG_WHISPER) + 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) @@ -171,7 +155,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( message_mods[WHISPER_MODE] = MODE_WHISPER_CRIT succumbed = TRUE else - src.log_talk(message, LOG_SAY, forced_by=forced) + log_talk(message, LOG_SAY, forced_by=forced) message = treat_message(message) // unfortunately we still need this var/sigreturn = SEND_SIGNAL(src, COMSIG_MOB_SAY, args) @@ -243,7 +227,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( deaf_type = 2 // Since you should be able to hear yourself without looking // Create map text prior to modifying message for goonchat - if (client?.prefs.chat_on_map && stat != UNCONSCIOUS && (client.prefs.see_chat_non_mob || ismob(speaker)) && can_hear()) + if (client?.prefs.chat_on_map && !(stat == UNCONSCIOUS || stat == HARD_CRIT) && (client.prefs.see_chat_non_mob || ismob(speaker)) && can_hear()) create_chat_message(speaker, message_language, raw_message, spans) // Recompose message for AI hrefs, language incomprehension. diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 8966f1f2b68..cf847de7146 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -74,7 +74,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 112b983d1b7..9121a1e4a97 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 d9fe624691d..4972a860dbf 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -224,7 +224,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/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 4dd3a60c82b..23ac9bfe57c 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -262,9 +262,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians if(amount > 0) to_chat(summoner, "Your [name] is under attack! You take damage!") summoner.visible_message("Blood sprays from [summoner] as [src] takes damage!") - if(summoner.stat == UNCONSCIOUS) - to_chat(summoner, "Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!") - summoner.adjustCloneLoss(amount * 0.5) //dying hosts take 50% bonus damage as cloneloss + switch(summoner.stat) + if(UNCONSCIOUS, HARD_CRIT) + to_chat(summoner, "Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!") + summoner.adjustCloneLoss(amount * 0.5) //dying hosts take 50% bonus damage as cloneloss update_health_hud() /mob/living/simple_animal/hostile/guardian/ex_act(severity, target) 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 7fbbc37664a..441c3062431 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 sentience_type = SENTIENCE_BOSS 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 fbcf5dfc7fb..63254b39bfb 100644 --- a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm +++ b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm @@ -9,7 +9,7 @@ speak_chance = 0 turns_per_move = 5 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 399279503da..c9c2e131cc0 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -15,7 +15,7 @@ speed = 0 maxHealth = 80 health = 80 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 harm_intent_damage = 10 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 63a752a04e0..fd109706d7a 100644 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm +++ b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm @@ -35,7 +35,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/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 78cfbb89214..d9241d7b7ab 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -42,7 +42,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 var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such 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 3e761423185..540b61b3333 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -20,7 +20,7 @@ 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 6995c066efa..17e1bb988a4 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm @@ -24,7 +24,7 @@ ranged_cooldown_time = 10 pass_flags = 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 7e406a0f8a8..870c3cd0c56 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm @@ -28,7 +28,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 b27ba353c3c..773c52f09af 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -165,14 +165,18 @@ GLOB.necropolis_gate.toggle_the_gate(null, TRUE) //very clever. return ..() + ///In addition to parent functionality, this will also turn the target into a small legion if they are unconcious. /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) + ///Resets the charge buffs. /mob/living/simple_animal/hostile/megafauna/legion/proc/reset_charge() 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 36bfd006d25..4601d83a42c 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 @@ -108,7 +108,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 43bbdb268b1..dce179b1b4a 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 @@ -16,7 +16,7 @@ aggro_vision_range = 18 environment_smash = ENVIRONMENT_SMASH_NONE //This is to prevent elites smashing up the mining station (entirely), we'll make sure they can smash minerals fine below. harm_intent_damage = 0 //Punching elites gets you nowhere - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT layer = LARGE_MOB_LAYER sentience_type = SENTIENCE_BOSS var/chosen_attack = 1 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 a5bb92b7bea..bf479c56e56 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 @@ -100,7 +100,7 @@ butcher_results = list(/obj/item/reagent_containers/food/snacks/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 food_type = list(/obj/item/reagent_containers/food/snacks/customizable/salad/ashsalad, /obj/item/reagent_containers/food/snacks/customizable/soup/ashsoup, /obj/item/reagent_containers/food/snacks/grown/ash_flora)//use lavaland plants to feed the lavaland monster tame_chance = 10 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 a108525d116..a14420b570c 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 @@ -29,7 +29,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 da2a3710150..ab82502021f 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 @@ -117,7 +117,7 @@ loot = list(/obj/item/organ/regenerative_core/legion) brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion del_on_death = 1 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = 1 var/dwarf_mob = FALSE var/mob/living/carbon/human/stored_mob @@ -183,16 +183,25 @@ attack_sound = 'sound/weapons/pierce.ogg' throw_message = "is shrugged off by" 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 view(src,1)) //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 range(src, 1)) //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/mining_mobs/ice demon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice demon.dm index 26c65574da9..bc36008ed2a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice demon.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice demon.dm @@ -36,7 +36,7 @@ crusher_loot = /obj/item/crusher_trophy/watcher_wing/ice_wing deathmessage = "fades as the energies that tied it to this world dissipate." deathsound = 'sound/magic/demon_dies.ogg' - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT movement_type = FLYING robust_searching = TRUE footstep_type = FOOTSTEP_MOB_CLAW diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice whelp.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice whelp.dm index 4f162bc5cf7..80f39f8eb3c 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice whelp.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice whelp.dm @@ -33,7 +33,7 @@ crusher_loot = /obj/item/crusher_trophy/tail_spike deathmessage = "collapses on its side." deathsound = 'sound/magic/demon_dies.ogg' - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = TRUE footstep_type = FOOTSTEP_MOB_CLAW /// How far the whelps fire can go diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm index 83aa4b55292..4bdb6e4071d 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm @@ -29,7 +29,7 @@ guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 1) loot = list() crusher_loot = /obj/item/crusher_trophy/goliath_tentacle - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = TRUE footstep_type = FOOTSTEP_MOB_CLAW /// Message for when the polar bear starts to attack faster diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm index 1f821e8c486..3d6e9a5384b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm @@ -31,7 +31,7 @@ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/stack/sheet/sinew/wolf = 2, /obj/item/stack/sheet/bone = 2) loot = list() crusher_loot = /obj/item/crusher_trophy/watcher_wing - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT robust_searching = TRUE footstep_type = FOOTSTEP_MOB_CLAW /// Message for when the wolf decides to start running away diff --git a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm index 7d104a94597..4417e68e2ec 100644 --- a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm +++ b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm @@ -10,7 +10,7 @@ speak_chance = 0 turns_per_move = 5 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 bcd644f263f..7ff44434782 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -258,7 +258,7 @@ melee_damage_lower = 20 melee_damage_upper = 40 armour_penetration = 30 - stat_attack = UNCONSCIOUS + stat_attack = HARD_CRIT attack_verb_continuous = "acts out divine vengeance on" attack_verb_simple = "act out divine vengeance on" obj_damage = 50 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 e0c2f0ddf60..5137b82ea2e 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm @@ -37,7 +37,7 @@ icon_gib = "syndicate_gib" turns_per_move = 5 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 e52cda0945b..477233566f3 100644 --- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -26,7 +26,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 faction = list("skeleton") see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE diff --git a/code/modules/mob/living/simple_animal/hostile/stickman.dm b/code/modules/mob/living/simple_animal/hostile/stickman.dm index 8f6fc393f11..1eb03b07650 100644 --- a/code/modules/mob/living/simple_animal/hostile/stickman.dm +++ b/code/modules/mob/living/simple_animal/hostile/stickman.dm @@ -10,7 +10,7 @@ speak_chance = 0 turns_per_move = 5 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 4fea16dbd68..24ef084847b 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -26,7 +26,7 @@ speak_chance = 0 turns_per_move = 5 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 756ecc33249..402bb278098 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 = MOB_ORGANIC|MOB_HUMANOID speak_chance = 0 - stat_attack = UNCONSCIOUS //braains + stat_attack = HARD_CRIT //braains maxHealth = 100 health = 100 harm_intent_damage = 5 diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index b1c00605db5..acb6fcc957b 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -24,11 +24,15 @@ 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/proc/AIprocess() // the master AI process @@ -138,22 +142,24 @@ bz_percentage = environment.gases[/datum/gas/bz][MOLES] / environment.total_moles() var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis - 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() - return //TODO: DEFERRED /mob/living/simple_animal/slime/handle_status_effects() ..() diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 3e18960a75f..7cddf00c0b8 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -200,18 +200,22 @@ /mob/living/simple_animal/slime/Process_Spacemove(movement_dir = 0) return 2 + /mob/living/simple_animal/slime/Stat() - if(..()) + . = ..() + if(!.) + return - if(!docile) - stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") - if(amount_grown >= SLIME_EVOLUTION_THRESHOLD) - if(is_adult) - stat(null, "You can reproduce!") - else - stat(null, "You can evolve!") + if(!docile) + stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") + if(amount_grown >= SLIME_EVOLUTION_THRESHOLD) + if(is_adult) + stat(null, "You can reproduce!") + else + stat(null, "You can evolve!") - if(stat == UNCONSCIOUS) + switch(stat) + if(HARD_CRIT, UNCONSCIOUS) stat(null,"You are knocked out by high levels of BZ!") else stat(null,"Power Level: [powerlevel]") @@ -420,7 +424,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 26bb2830dc9..22baf03e4ac 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -156,7 +156,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 @@ -915,7 +915,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 4cb0cbe892a..78f130f9dc0 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -42,18 +42,34 @@ if(!old_eye_blind || !eye_blind && !HAS_TRAIT(src, TRAIT_BLIND)) update_blindness() + /// proc that adds and removes blindness overlays when necessary /mob/proc/update_blindness() - 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) - throw_alert("blind", /obj/screen/alert/blind) + switch(stat) + if(CONSCIOUS, SOFT_CRIT) + if(HAS_TRAIT(src, TRAIT_BLIND) || eye_blind) + throw_alert("blind", /obj/screen/alert/blind) + do_set_blindness(TRUE) + else + do_set_blindness(FALSE) + if(UNCONSCIOUS, HARD_CRIT) + do_set_blindness(TRUE) + if(DEAD) + do_set_blindness(FALSE) + + +///Proc that handles adding and removing the blindness overlays. +/mob/proc/do_set_blindness(now_blind) + if(now_blind) overlay_fullscreen("blind", /obj/screen/fullscreen/blind) // You are blind why should you be able to make out details like color, only shapes near you add_client_colour(/datum/client_colour/monochrome/blind) - else // CONSCIOUS no blind trait, no blindness + else clear_alert("blind") clear_fullscreen("blind") remove_client_colour(/datum/client_colour/monochrome/blind) + + /** * Make the mobs vision blurry */ diff --git a/code/modules/research/nanites/nanite_programs/protocols.dm b/code/modules/research/nanites/nanite_programs/protocols.dm index 216a1349797..89b6acf42aa 100644 --- a/code/modules/research/nanites/nanite_programs/protocols.dm +++ b/code/modules/research/nanites/nanite_programs/protocols.dm @@ -89,17 +89,12 @@ protocol_class = NANITE_PROTOCOL_REPLICATION var/boost = 3 + /datum/nanite_program/protocol/offline/check_conditions() - var/is_offline = FALSE - if(nanites.host_mob.stat >= UNCONSCIOUS) //DEAD or UNCONSCIOUS - is_offline = TRUE - if(nanites.host_mob.InCritical() && !HAS_TRAIT(nanites.host_mob, TRAIT_NOSOFTCRIT)) - is_offline = TRUE - if(nanites.host_mob.InFullCritical() && !HAS_TRAIT(nanites.host_mob, TRAIT_NOHARDCRIT)) - is_offline = TRUE - if(!is_offline) + if(nanites.host_mob.stat == CONSCIOUS) return FALSE return ..() + /datum/nanite_program/protocol/offline/active_effect() nanites.adjust_nanites(null, boost) diff --git a/code/modules/research/nanites/nanite_programs/sensor.dm b/code/modules/research/nanites/nanite_programs/sensor.dm index fbebeaf209a..07a1f622eb6 100644 --- a/code/modules/research/nanites/nanite_programs/sensor.dm +++ b/code/modules/research/nanites/nanite_programs/sensor.dm @@ -110,14 +110,14 @@ 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 f496abe6e1f..7eb793cd832 100644 --- a/code/modules/research/nanites/rules.dm +++ b/code/modules/research/nanites/rules.dm @@ -55,9 +55,8 @@ 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/head.dm b/code/modules/surgery/bodyparts/head.dm index 5e83395ba7f..aa35dd70646 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 && !((owner.stat == DEAD) || owner.InFullCritical())) + if(owner && owner.stat <= HARD_CRIT) return FALSE return ..() diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 2c0e549b761..ac58398f282 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -14,7 +14,7 @@ wound_resistance = 10 /obj/item/bodypart/chest/can_dismember(obj/item/I) - if(!((owner.stat == DEAD) || owner.InFullCritical()) || !get_organs()) + if(owner.stat <= HARD_CRIT || !get_organs()) return FALSE return ..() diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 2baea55b151..b7edd798ca8 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -51,29 +51,30 @@ 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 == UNCONSCIOUS) - addtimer(CALLBACK(src, .proc/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/heal), 3 SECONDS) + 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 != UNCONSCIOUS) - 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 +98,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/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 6bee31c6045..0cfb060da2e 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -393,7 +393,7 @@ patient.visible_message("[user] begins to secure [src] around [patient]'s [candidate_name].", "[user] begins to secure [src] around your [candidate_name]!") playsound(get_turf(patient), 'sound/items/ratchet.ogg', 20, TRUE) - if(patient.stat == DEAD || patient.stat == UNCONSCIOUS || patient.IsStun()) //Stun is used by paralytics like curare it should not be confused with the more common paralyze. + if(patient.stat >= UNCONSCIOUS || patient.IsStun()) //Stun is used by paralytics like curare it should not be confused with the more common paralyze. amputation_speed_mod = 0.5 else if(patient.jitteriness >= 1) amputation_speed_mod = 1.5