Skip to content

Commit

Permalink
Mobility Atomization 7: Crit Status and Succumbing alert (#10900)
Browse files Browse the repository at this point in the history
* tgstation/tgstation#53117

* tgstation/tgstation#52892

* thanks ryll

* fix blindness

* fix broken succumb
  • Loading branch information
Tsar-Salat authored Apr 28, 2024
1 parent b748df3 commit 6644ae0
Show file tree
Hide file tree
Showing 77 changed files with 290 additions and 217 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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))
3 changes: 2 additions & 1 deletion code/__DEFINES/stat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
17 changes: 17 additions & 0 deletions code/_onclick/hud/alert.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 5 additions & 4 deletions code/datums/diseases/advance/symptoms/heal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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, "<span class='warning'>You feel yourself slip into a deep, regenerative slumber.</span>")
Expand Down
2 changes: 1 addition & 1 deletion code/datums/emotes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
switch(user.stat)
if(SOFT_CRIT)
to_chat(user, "<span class='notice'>You cannot [key] while in a critical condition.</span>")
if(UNCONSCIOUS)
if(UNCONSCIOUS, HARD_CRIT)
to_chat(user, "<span class='notice'>You cannot [key] while unconscious.</span>")
if(DEAD)
to_chat(user, "<span class='notice'>You cannot [key] while dead.</span>")
Expand Down
2 changes: 1 addition & 1 deletion code/game/data_huds.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion code/game/gamemodes/game_mode.dm
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@
if(L.suiciding) //Suicider
msg += "<b>[L.name]</b> ([L.key]), the [L.job] (<span class='boldannounce'>Suicide</span>)\n"
failed = TRUE //Disconnected client
if(!failed && L.stat == UNCONSCIOUS)
if(!failed && (L.stat == UNCONSCIOUS || L.stat == HARD_CRIT))
msg += "<b>[L.name]</b> ([L.key]), the [L.job] (Dying)\n"
failed = TRUE //Unconscious
if(!failed && L.stat == DEAD)
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/computer/Operating.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/computer/aifixer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
4 changes: 3 additions & 1 deletion code/modules/admin/admin_more_info.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
if(SOFT_CRIT)
status = "<font color='orange'><b>Dying</b></font>"
if(UNCONSCIOUS)
status = "<font color='orange'><b>[L.InCritical() ? "Unconscious and Dying" : "Unconscious"]</b></font>"
status = "<font color='orange'><b>Unconscious</b></font>"
if(HARD_CRIT)
status = "<font color='orange'><b>Unconscious and Dying</b></font>"
if(DEAD)
status = "<font color='red'><b>Dead</b></font>"
health_description = "Status = [status]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion code/modules/antagonists/changeling/changeling_power.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/changeling/powers/fleshmend.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/changeling/powers/panacea.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/changeling/powers/regenerate.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
..()
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/cult/runes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(new_human, "<span class='cultitalic'><b>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.</b></span>")

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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/heretic/heretic_antag.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/holoparasite/holoparasite_team.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 8 additions & 7 deletions code/modules/awaymissions/capture_the_flag.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
6 changes: 3 additions & 3 deletions code/modules/awaymissions/mission_code/TheFactory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion code/modules/client/verbs/suicide.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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!")
Expand Down
2 changes: 1 addition & 1 deletion code/modules/client/verbs/who.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
else
entry += " - Playing as [C.mob.real_name]"
switch(C.mob.stat)
if(UNCONSCIOUS)
if(UNCONSCIOUS, HARD_CRIT)
entry += " - <font color='darkgray'><b>Unconscious</b></font>"
if(DEAD)
if(isobserver(C.mob))
Expand Down
12 changes: 7 additions & 5 deletions code/modules/events/heart_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/flufftext/Dreaming.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion code/modules/holoparasite/_holoparasite.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion code/modules/holoparasite/holoparasite_damage.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/holoparasite/holoparasite_holder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
13 changes: 7 additions & 6 deletions code/modules/mob/living/carbon/carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down
Loading

0 comments on commit 6644ae0

Please sign in to comment.