diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 593419b61b15b..7e8493059dcaa 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -40,6 +40,9 @@
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
#define XENO_HOST 16384 //Tracks whether we're gonna be a baby alien's mummy.
+//Health Defines
+#define HEALTH_THRESHOLD_CRIT 0
+#define HEALTH_THRESHOLD_DEAD -100
//Grab levels
#define GRAB_PASSIVE 1
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 3a2ff120af301..71a3bce0fbe2e 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -100,10 +100,6 @@
//game_options.txt configs
- var/health_threshold_softcrit = 0
- var/health_threshold_crit = 0
- var/health_threshold_dead = -100
-
var/bones_can_break = 1
var/revival_pod_plants = 1
@@ -663,10 +659,6 @@
value = text2num(value)
switch(name)
- if("health_threshold_crit")
- config.health_threshold_crit = value
- if("health_threshold_dead")
- config.health_threshold_dead = value
if("revival_pod_plants")
config.revival_pod_plants = value
if("revival_cloning")
diff --git a/code/datums/diseases/critical.dm b/code/datums/diseases/critical.dm
new file mode 100644
index 0000000000000..82748802cce7f
--- /dev/null
+++ b/code/datums/diseases/critical.dm
@@ -0,0 +1,130 @@
+/datum/disease/critical
+
+/datum/disease/critical/stage_act() //overriden to ensure unique behavior
+ stage = min(stage, max_stages)
+
+ if(prob(stage_prob))
+ stage = min(stage + 1, max_stages)
+
+ for(var/C_id in cures)
+ if(affected_mob.reagents.has_reagent(C_id))
+ if(prob(cure_chance))
+ cure()
+ return FALSE
+ return TRUE
+
+/datum/disease/critical/shock
+ name = "Shock"
+ form = "Medical Emergency"
+ spread_text = "The patient is in shock"
+ max_stages = 3
+ spread_flags = SPECIAL
+ cure_text = "Saline Solution"
+ cures = list("salglu_solution")
+ cure_chance = 10
+ viable_mobtypes = list(/mob/living/carbon/human)
+ stage_prob = 6
+ severity = DANGEROUS
+ disease_flags = CURABLE
+ bypasses_immunity = TRUE
+ virus_heal_resistant = TRUE
+
+/datum/disease/critical/shock/stage_act()
+ if(..())
+ if(affected_mob.health >= 25)
+ to_chat(affected_mob, "You feel better.")
+ cure()
+ return
+ switch(stage)
+ if(1)
+ if(prob(1) && prob(10))
+ to_chat(affected_mob, "You feel better.")
+ cure()
+ return
+ if(prob(8))
+ affected_mob.emote(pick("shiver", "pale", "moan"))
+ if(prob(5))
+ to_chat(affected_mob, "You feel weak!")
+ if(2)
+ if(prob(1) && prob(10))
+ to_chat(affected_mob, "You feel better.")
+ cure()
+ return
+ if(prob(8))
+ affected_mob.emote(pick("shiver", "pale", "moan", "shudder", "tremble"))
+ if(prob(5))
+ to_chat(affected_mob, "You feel absolutely terrible!")
+ if(prob(5))
+ affected_mob.emote("faint", "collapse", "groan")
+ if(3)
+ if(prob(1) && prob(10))
+ to_chat(affected_mob, "You feel better.")
+ cure()
+ return
+ if(prob(8))
+ affected_mob.emote(pick("shudder", "pale", "tremble", "groan", "bshake"))
+ if(prob(5))
+ to_chat(affected_mob, "You feel horrible!")
+ if(prob(5))
+ affected_mob.emote(pick("faint", "collapse", "groan"))
+ if(prob(7))
+ to_chat(affected_mob, "You can't breathe!")
+ affected_mob.AdjustLoseBreath(1)
+ if(prob(5))
+ var/datum/disease/D = new /datum/disease/critical/heart_failure
+ affected_mob.ForceContractDisease(D)
+
+/datum/disease/critical/heart_failure
+ name = "Cardiac Failure"
+ form = "Medical Emergency"
+ spread_text = "The patient is having a cardiac emergency"
+ max_stages = 3
+ spread_flags = SPECIAL
+ cure_text = "Cardiac Stimulants"
+ cures = list("atropine", "epinephrine")
+ cure_chance = 10
+ needs_all_cures = FALSE
+ viable_mobtypes = list(/mob/living/carbon/human)
+ stage_prob = 5
+ severity = DANGEROUS
+ disease_flags = CURABLE
+ required_organs = list(/obj/item/organ/internal/heart)
+ bypasses_immunity = TRUE
+ virus_heal_resistant = TRUE
+
+/datum/disease/critical/heart_failure/stage_act()
+ if(..())
+ switch(stage)
+ if(1)
+ if(prob(1) && prob(10))
+ to_chat(affected_mob, "You feel better.")
+ cure()
+ return
+ if(prob(8))
+ affected_mob.emote(pick("pale", "shudder"))
+ if(prob(5))
+ to_chat(affected_mob, "Your arm hurts!")
+ else if(prob(5))
+ to_chat(affected_mob, "Your chest hurts!")
+ if(2)
+ if(prob(1) && prob(10))
+ to_chat(affected_mob, "You feel better.")
+ cure()
+ return
+ if(prob(8))
+ affected_mob.emote(pick("pale", "groan"))
+ if(prob(5))
+ to_chat(affected_mob, "Your heart lurches in your chest!")
+ affected_mob.AdjustLoseBreath(1)
+ if(prob(3))
+ to_chat(affected_mob, "Your heart stops beating!")
+ affected_mob.AdjustLoseBreath(3)
+ if(prob(5))
+ affected_mob.emote(pick("faint", "collapse", "groan"))
+ if(3)
+ affected_mob.adjustOxyLoss(1)
+ if(prob(8))
+ affected_mob.emote(pick("twitch", "gasp"))
+ if(prob(5) && ishuman(affected_mob))
+ var/mob/living/carbon/human/H = affected_mob
+ H.set_heartattack(TRUE)
\ No newline at end of file
diff --git a/code/datums/diseases/food_poisoning.dm b/code/datums/diseases/food_poisoning.dm
index 79a3801ce103d..fe02057478bd9 100644
--- a/code/datums/diseases/food_poisoning.dm
+++ b/code/datums/diseases/food_poisoning.dm
@@ -14,20 +14,12 @@
disease_flags = CURABLE
spread_flags = NON_CONTAGIOUS
virus_heal_resistant = TRUE
- var/remissive = 0
/datum/disease/food_poisoning/stage_act()
- if(!remissive)
- ..()
if(affected_mob.sleeping && prob(33))
to_chat(affected_mob, "You feel better.")
- remissive = 1
- if(remissive)
- if(prob(stage_prob))
- stage--
- if(stage == 0)
- cure()
- return
+ cure()
+ return
switch(stage)
if(1)
if(prob(5))
diff --git a/code/datums/spells/inflict_handler.dm b/code/datums/spells/inflict_handler.dm
index cfda930afd249..896e399187a3d 100644
--- a/code/datums/spells/inflict_handler.dm
+++ b/code/datums/spells/inflict_handler.dm
@@ -44,7 +44,7 @@
else if(amt_dam_fire <= 0)
target.heal_overall_damage(amt_dam_brute,amt_dam_fire)
target.adjustToxLoss(amt_dam_tox)
- target.oxyloss += amt_dam_oxy
+ target.adjustOxyLoss(amt_dam_oxy)
//disabling
target.Weaken(amt_weakened)
target.Paralyse(amt_paralysis)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 91132a5f9bd90..024b2a924cf50 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -680,10 +680,10 @@ var/list/blood_splatter_icons = list()
return pass_flags&passflag
/atom/proc/isinspace()
- if(istype(get_turf(src), /turf/space))
- return 1
+ if(isspaceturf(get_turf(src)))
+ return TRUE
else
- return 0
+ return FALSE
/atom/proc/handle_fall()
return
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 178605853e882..461de475b41cc 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -78,10 +78,11 @@
return 1
return 0
-//helper for getting the appropriate health status UPDATED BY PUCKABOO2 TO INCLUDE NEGATIVES.
+//helper for getting the appropriate health status
/proc/RoundHealth(mob/living/M)
if(M.stat == DEAD || (M.status_flags & FAKEDEATH))
- return "health-100" //what's our health? it doesn't matter, we're dead, or faking
+ return "health-100-dead" //what's our health? it doesn't matter, we're dead, or faking
+
var/maxi_health = M.maxHealth
if(iscarbon(M) && M.health < 0)
maxi_health = 100 //so crit shows up right for aliens and other high-health carbon mobs; noncarbons don't have crit.
@@ -91,7 +92,7 @@
if(100 to INFINITY)
return "health100"
if(95 to 100)
- return "health95" //For telling patients to eat a warm donk pocket and go on with their shift.
+ return "health95"
if(90 to 95)
return "health90"
if(80 to 90)
@@ -127,13 +128,13 @@
if(-70 to -60)
return "health-60"
if(-80 to -70)
- return "health-70" //Doc?
+ return "health-70"
if(-90 to -80)
- return "health-80" //Hey, doc?
+ return "health-80"
if(-100 to -90)
- return "health-90" //HURRY UP, DOC!
+ return "health-90"
else
- return "health-100" //doc u had 1 job
+ return "health-100" //past this point, you're just in trouble
return "0"
@@ -438,4 +439,4 @@
if(weedlevel < 1) // You don't want to see these icons if the value is small
holder.icon_state = ""
return
- holder.icon_state = "hudweed[RoundPlantBar(weedlevel/10)]"
+ holder.icon_state = "hudweed[RoundPlantBar(weedlevel/10)]"
\ No newline at end of file
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index 708d8467fb03c..e4b1f1e8a49e5 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -537,7 +537,7 @@
occupantData["isViableSubject"] = 0
occupantData["health"] = connected.occupant.health
occupantData["maxHealth"] = connected.occupant.maxHealth
- occupantData["minHealth"] = config.health_threshold_dead
+ occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD
occupantData["uniqueEnzymes"] = connected.occupant.dna.unique_enzymes
occupantData["uniqueIdentity"] = connected.occupant.dna.uni_identity
occupantData["structuralEnzymes"] = connected.occupant.dna.struc_enzymes
diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm
index 6dbd4badc3080..21d97863105e3 100644
--- a/code/game/gamemodes/changeling/powers/fleshmend.dm
+++ b/code/game/gamemodes/changeling/powers/fleshmend.dm
@@ -40,9 +40,6 @@
// The healing itself - doesn't heal toxin damage
// (that's anatomic panacea) and the effectiveness decreases with
// each use in a short timespan
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- H.shock_stage = 0
for(var/i in 1 to healing_ticks)
if(user)
var/healpertick = -(total_healing / healing_ticks)
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index 83f221a95d37c..1fef93d0f13d9 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -27,8 +27,6 @@
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.restore_blood()
- H.traumatic_shock = 0
- H.shock_stage = 0
H.next_pain_time = 0
H.dna.species.create_organs(H)
// Now that recreating all organs is necessary, the rest of this organ stuff probably
@@ -51,6 +49,8 @@
IO.rejuvenate()
IO.trace_chemicals.Cut()
H.remove_all_embedded_objects()
+ for(var/datum/disease/critical/C in user.viruses)
+ C.cure()
user.status_flags &= ~(FAKEDEATH)
user.updatehealth("revive sting")
user.update_blind_effects()
diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm
index d344074a33180..f339be06b8891 100644
--- a/code/game/gamemodes/miniantags/guardian/guardian.dm
+++ b/code/game/gamemodes/miniantags/guardian/guardian.dm
@@ -102,7 +102,7 @@
if(summoner)
var/resulthealth
if(iscarbon(summoner))
- resulthealth = round((abs(config.health_threshold_dead - summoner.health) / abs(config.health_threshold_dead - summoner.maxHealth)) * 100)
+ resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - summoner.health) / abs(HEALTH_THRESHOLD_DEAD - summoner.maxHealth)) * 100)
else
resulthealth = round((summoner.health / summoner.maxHealth) * 100)
if(hud_used)
diff --git a/code/game/gamemodes/scoreboard.dm b/code/game/gamemodes/scoreboard.dm
index 9a3ca6073a125..bd17175eaa240 100644
--- a/code/game/gamemodes/scoreboard.dm
+++ b/code/game/gamemodes/scoreboard.dm
@@ -59,7 +59,7 @@
score_richestjob = E.job
score_richestkey = E.key
- dmg_score = E.bruteloss + E.fireloss + E.toxloss + E.oxyloss
+ dmg_score = E.getBruteLoss() + E.getFireLoss() + E.getToxLoss() + E.getOxyLoss()
if(dmg_score > score_dmgestdamage)
score_dmgestdamage = dmg_score
score_dmgestname = E.real_name
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 917c198af2f46..c447ff26e72a3 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -149,7 +149,7 @@
occupantData["stat"] = occupant.stat
occupantData["health"] = occupant.health
occupantData["maxHealth"] = occupant.maxHealth
- occupantData["minHealth"] = config.health_threshold_dead
+ occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()
occupantData["toxLoss"] = occupant.getToxLoss()
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 17a27812499b5..3c24a5064c0ff 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -34,7 +34,7 @@
var/obj/effect/countdown/clonepod/countdown
- var/list/brine_types = list("corazone", "salbutamol", "hydrocodone")
+ var/list/brine_types = list("corazone", "salbutamol", "epinephrine", "salglu_solution") //stops heart attacks, heart failure, shock, and keeps their O2 levels normal
var/list/missing_organs
var/organs_number = 0
@@ -479,7 +479,6 @@
occupant.forceMove(get_turf(src))
occupant.update_body()
domutcheck(occupant) //Waiting until they're out before possible notransform.
- occupant.shock_stage = 0 //Reset Shock
occupant.special_post_clone_handling()
occupant = null
update_icon()
diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm
index c338a0f32c9d7..c4c8d342aebe7 100644
--- a/code/game/machinery/computer/Operating.dm
+++ b/code/game/machinery/computer/Operating.dm
@@ -112,7 +112,7 @@
occupantData["stat"] = occupant.stat
occupantData["health"] = occupant.health
occupantData["maxHealth"] = occupant.maxHealth
- occupantData["minHealth"] = config.health_threshold_dead
+ occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()
occupantData["toxLoss"] = occupant.getToxLoss()
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index fc60d8f005d54..d05ec96133d6a 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -208,7 +208,7 @@
occupantData["stat"] = occupant.stat
occupantData["health"] = occupant.health
occupantData["maxHealth"] = occupant.maxHealth
- occupantData["minHealth"] = config.health_threshold_dead
+ occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()
occupantData["toxLoss"] = occupant.getToxLoss()
@@ -378,9 +378,9 @@
occupant.Paralyse(max(5/efficiency, (1/occupant.bodytemperature)*3000/efficiency))
if(air_contents.oxygen > 2)
if(occupant.getOxyLoss())
- occupant.adjustOxyLoss(-10)
+ occupant.adjustOxyLoss(-6)
else
- occupant.adjustOxyLoss(-2)
+ occupant.adjustOxyLoss(-1.2)
if(beaker && next_trans == 0)
var/proportion = 10 * min(1/beaker.volume, 1)
// Yes, this means you can get more bang for your buck with a beaker of SF vs a patch
@@ -388,7 +388,7 @@
beaker.reagents.reaction(occupant, TOUCH, proportion)
beaker.reagents.trans_to(occupant, 1, 10)
next_trans++
- if(next_trans == 10)
+ if(next_trans == 17)
next_trans = 0
/obj/machinery/atmospherics/unary/cryo_cell/proc/heat_gas_contents()
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index fb780e5d550c9..33a2e2840ac08 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -1015,13 +1015,16 @@
icon_deny = "med-deny"
product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!"
req_access_txt = "5"
- products = list(/obj/item/reagent_containers/glass/bottle/charcoal = 4,/obj/item/reagent_containers/glass/bottle/morphine = 4,/obj/item/reagent_containers/glass/bottle/ether = 4,/obj/item/reagent_containers/glass/bottle/epinephrine = 4,
- /obj/item/reagent_containers/glass/bottle/toxin = 4,/obj/item/reagent_containers/syringe/antiviral = 6,/obj/item/reagent_containers/syringe/insulin = 4,
- /obj/item/reagent_containers/syringe = 12,/obj/item/healthanalyzer = 5,/obj/item/healthupgrade = 5,/obj/item/reagent_containers/glass/beaker = 4, /obj/item/reagent_containers/hypospray/safety = 2,
- /obj/item/reagent_containers/dropper = 2,/obj/item/stack/medical/bruise_pack/advanced = 3, /obj/item/stack/medical/ointment/advanced = 3,
- /obj/item/stack/medical/bruise_pack = 3,/obj/item/stack/medical/splint = 4, /obj/item/sensor_device = 2, /obj/item/reagent_containers/hypospray/autoinjector = 4,
- /obj/item/pinpointer/crew = 2)
- contraband = list(/obj/item/reagent_containers/glass/bottle/pancuronium = 1,/obj/item/reagent_containers/glass/bottle/sulfonal = 1)
+ products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/food/pill/patch/styptic = 10, /obj/item/reagent_containers/food/pill/patch/silver_sulf = 10,
+ /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/diphenhydramine = 4,
+ /obj/item/reagent_containers/glass/bottle/salicylic = 4, /obj/item/reagent_containers/glass/bottle/potassium_iodide =3, /obj/item/reagent_containers/glass/bottle/saline = 5,
+ /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/ether = 4, /obj/item/reagent_containers/glass/bottle/atropine = 3,
+ /obj/item/reagent_containers/glass/bottle/oculine = 2, /obj/item/reagent_containers/glass/bottle/toxin = 4, /obj/item/reagent_containers/syringe/antiviral = 6,
+ /obj/item/reagent_containers/syringe/insulin = 6, /obj/item/reagent_containers/syringe/calomel = 10, /obj/item/reagent_containers/hypospray/autoinjector = 5, /obj/item/reagent_containers/food/pill/salbutamol = 10,
+ /obj/item/reagent_containers/food/pill/mannitol = 10, /obj/item/reagent_containers/food/pill/mutadone = 5, /obj/item/stack/medical/bruise_pack/advanced = 4, /obj/item/stack/medical/ointment/advanced = 4, /obj/item/stack/medical/bruise_pack = 4,
+ /obj/item/stack/medical/splint = 4, /obj/item/reagent_containers/glass/beaker = 4, /obj/item/reagent_containers/dropper = 4, /obj/item/healthanalyzer = 4,
+ /obj/item/healthupgrade = 4, /obj/item/reagent_containers/hypospray/safety = 2, /obj/item/sensor_device = 2, /obj/item/pinpointer/crew = 2)
+ contraband = list(/obj/item/reagent_containers/glass/bottle/sulfonal = 1, /obj/item/reagent_containers/glass/bottle/pancuronium = 1)
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0)
//This one's from bay12
@@ -1041,7 +1044,7 @@
icon_deny = "wallmed-deny"
req_access_txt = "5"
density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude
- products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/reagent_containers/hypospray/autoinjector = 4,/obj/item/healthanalyzer = 1)
+ products = list(/obj/item/stack/medical/bruise_pack = 2, /obj/item/stack/medical/ointment = 2, /obj/item/reagent_containers/hypospray/autoinjector = 4, /obj/item/healthanalyzer = 1)
contraband = list(/obj/item/reagent_containers/syringe/charcoal = 4,/obj/item/reagent_containers/syringe/antiviral = 4,/obj/item/reagent_containers/food/pill/tox = 1)
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0)
diff --git a/code/game/objects/items/devices/handheld_defib.dm b/code/game/objects/items/devices/handheld_defib.dm
new file mode 100644
index 0000000000000..199aaf43737f8
--- /dev/null
+++ b/code/game/objects/items/devices/handheld_defib.dm
@@ -0,0 +1,91 @@
+/obj/item/handheld_defibrillator
+ name = "handheld defibrillator"
+ desc = "Used to restart stopped hearts."
+ icon = 'icons/goonstation/objects/objects.dmi'
+ lefthand_file = 'icons/goonstation/mob/inhands/items_lefthand.dmi'
+ righthand_file = 'icons/goonstation/mob/inhands/items_righthand.dmi'
+ icon_state = "defib-on"
+ item_state = "defib"
+
+ var/icon_base = "defib"
+ var/cooldown = FALSE
+ var/charge_time = 100
+ var/emagged = FALSE
+
+/obj/item/handheld_defibrillator/emag_act(mob/user)
+ if(!emagged)
+ emagged = TRUE
+ desc += " The screen only shows the word KILL flashing over and over."
+ if(user)
+ to_chat(user, "you short out the safeties on [src]")
+ else
+ emagged = FALSE
+ desc = "Used to restart stopped hearts."
+ if(user)
+ to_chat(user, "You restore the safeties on [src]")
+
+/obj/item/handheld_defibrillator/emp_act(severity)
+ if(emagged)
+ emagged = FALSE
+ desc = "Used to restart stopped hearts."
+ visible_message("[src] beeps: Safety protocols enabled!")
+ playsound(get_turf(src), 'sound/machines/defib_saftyon.ogg', 50, 0)
+ else
+ emagged = TRUE
+ desc += " The screen only shows the word KILL flashing over and over."
+ visible_message("[src] beeps: Safety protocols disabled!")
+ playsound(get_turf(src), 'sound/machines/defib_saftyoff.ogg', 50, 0)
+
+/obj/item/handheld_defibrillator/attack(mob/living/carbon/human/H, mob/user)
+ if(!istype(H))
+ return ..()
+
+ if(cooldown)
+ to_chat(user, "[src] is still charging!")
+ return
+
+ if(emagged || (H.health <= HEALTH_THRESHOLD_CRIT) || (H.undergoing_cardiac_arrest()))
+ user.visible_message("[user] shocks [H] with [src].", "You shock [H] with [src].")
+ add_attack_logs(user, H, "defibrillated with [src]")
+ playsound(user.loc, "sound/weapons/Egloves.ogg", 75, 1)
+
+ if(H.stat == DEAD)
+ to_chat(user, "[H] doesn't respond at all!")
+ else
+ H.set_heartattack(FALSE)
+ var/total_damage = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss()
+ if(H.health <= HEALTH_THRESHOLD_CRIT)
+ if(total_damage >= 90)
+ to_chat(user, "[H] looks horribly injured. Resuscitation alone may not help revive them.")
+ if(prob(66))
+ to_chat(user, "[H] inhales deeply!")
+ H.adjustOxyLoss(-50)
+ else
+ to_chat(user, "[H] doesn't respond!")
+
+ H.AdjustParalysis(3)
+ H.AdjustStunned(5)
+ H.AdjustWeakened(5)
+ H.AdjustStuttering(10)
+ to_chat(H, "You feel a powerful jolt!")
+ H.shock_internal_organs(100)
+
+ if(emagged && prob(10))
+ to_chat(user, "[src]'s on board scanner indicates that the target is undergoing a cardiac arrest!")
+ H.set_heartattack(TRUE)
+
+ cooldown = TRUE
+ icon_state = "[icon_base]-shock"
+ addtimer(CALLBACK(src, .proc/short_charge), 10)
+ addtimer(CALLBACK(src, .proc/recharge), charge_time)
+
+ else
+ to_chat(user, "[src]'s on board medical scanner indicates that no shock is required.")
+
+/obj/item/handheld_defibrillator/proc/short_charge()
+ icon_state = "[icon_base]-off"
+
+/obj/item/handheld_defibrillator/proc/recharge()
+ cooldown = FALSE
+ icon_state = "[icon_base]-on"
+ playsound(loc, "sound/weapons/flash.ogg", 75, 1)
\ No newline at end of file
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 8ad7fae6d2d04..4a20a52fa0489 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -125,8 +125,8 @@ REAGENT SCANNER
var/mode = 1;
-/obj/item/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
- if(( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
+/obj/item/healthanalyzer/attack(mob/living/M, mob/living/user)
+ if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
to_chat(user, text("You try to analyze the floor's vitals!"))
for(var/mob/O in viewers(M, null))
O.show_message(text("[user] has analyzed the floor's vitals!"), 1)
@@ -137,7 +137,7 @@ REAGENT SCANNER
return
user.visible_message("[user] has analyzed [M]'s vitals."," You have analyzed [M]'s vitals.")
- if(!istype(M,/mob/living/carbon/human) || M.isSynthetic())
+ if(!ishuman(M) || M.isSynthetic())
//these sensors are designed for organic life
user.show_message("Analyzing Results for ERROR:\n\t Overall Status: ERROR")
user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1)
@@ -147,122 +147,132 @@ REAGENT SCANNER
user.show_message("Subject's pulse: -- bpm.")
return
- var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
- var/OX = M.getOxyLoss() > 50 ? "[M.getOxyLoss()]" : M.getOxyLoss()
- var/TX = M.getToxLoss() > 50 ? "[M.getToxLoss()]" : M.getToxLoss()
- var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss()
- var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss()
- if(M.status_flags & FAKEDEATH)
+ var/mob/living/carbon/human/H = M
+ var/fake_oxy = max(rand(1,40), H.getOxyLoss(), (300 - (H.getToxLoss() + H.getFireLoss() + H.getBruteLoss())))
+ var/OX = H.getOxyLoss() > 50 ? "[H.getOxyLoss()]" : H.getOxyLoss()
+ var/TX = H.getToxLoss() > 50 ? "[H.getToxLoss()]" : H.getToxLoss()
+ var/BU = H.getFireLoss() > 50 ? "[H.getFireLoss()]" : H.getFireLoss()
+ var/BR = H.getBruteLoss() > 50 ? "[H.getBruteLoss()]" : H.getBruteLoss()
+ if(H.status_flags & FAKEDEATH)
OX = fake_oxy > 50 ? "[fake_oxy]" : fake_oxy
- user.show_message("Analyzing Results for [M]:\n\t Overall Status: dead")
+ user.show_message("Analyzing Results for [H]:\n\t Overall Status: dead")
else
- user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"]")
+ user.show_message("Analyzing Results for [H]:\n\t Overall Status: [H.stat > 1 ? "dead" : "[H.health]% healthy"]")
user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\t Damage Specifics: [OX] - [TX] - [BU] - [BR]")
- user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
- if(M.timeofdeath && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
- user.show_message("Time of Death: [station_time_timestamp("hh:mm:ss", M.timeofdeath)]")
- var/tdelta = round(world.time - M.timeofdeath)
+ user.show_message("Body Temperature: [H.bodytemperature-T0C]°C ([H.bodytemperature*1.8-459.67]°F)", 1)
+ if(H.timeofdeath && (H.stat == DEAD || (H.status_flags & FAKEDEATH)))
+ user.show_message("Time of Death: [station_time_timestamp("hh:mm:ss", H.timeofdeath)]")
+ var/tdelta = round(world.time - H.timeofdeath)
if(tdelta < (DEFIB_TIME_LIMIT * 10))
user.show_message("Subject died [DisplayTimeText(tdelta)] ago, defibrillation may be possible!")
- if(istype(M, /mob/living/carbon/human) && mode == 1)
- var/mob/living/carbon/human/H = M
+ if(mode == 1)
var/list/damaged = H.get_damaged_organs(1,1)
user.show_message("Localized Damage, Brute/Burn:",1)
if(length(damaged) > 0)
for(var/obj/item/organ/external/org in damaged)
user.show_message("\t\t[capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]")
- OX = M.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal"
- TX = M.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal"
- BU = M.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K"
- BR = M.getBruteLoss() > 50 ? "Severe anatomical damage detected" : "Subject brute-force injury status O.K"
- if(M.status_flags & FAKEDEATH)
+ OX = H.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal"
+ TX = H.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal"
+ BU = H.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K"
+ BR = H.getBruteLoss() > 50 ? "Severe anatomical damage detected" : "Subject brute-force injury status O.K"
+ if(H.status_flags & FAKEDEATH)
OX = fake_oxy > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal"
user.show_message("[OX] | [TX] | [BU] | [BR]")
- if(istype(M, /mob/living/carbon))
- if(upgraded)
- chemscan(user, M)
- for(var/thing in M.viruses)
- var/datum/disease/D = thing
- if(!(D.visibility_flags & HIDDEN_SCANNER))
- user.show_message("Warning: [D.form] detected\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]")
- if(M.getStaminaLoss())
+
+ if(upgraded)
+ chemscan(user, H)
+ for(var/thing in H.viruses)
+ var/datum/disease/D = thing
+ if(!(D.visibility_flags & HIDDEN_SCANNER))
+ user.show_message("Warning: [D.form] detected\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]")
+ if(H.undergoing_cardiac_arrest())
+ var/obj/item/organ/internal/heart/heart = H.get_int_organ(/obj/item/organ/internal/heart)
+ if(heart && !(heart.status & ORGAN_DEAD))
+ user.show_message("Warning: Medical Emergency detected\nName: Cardiac Arrest.\nType: The patient's heart has stopped.\nStage: 1/1.\nPossible Cure: Electric Shock")
+ else if(heart && (heart.status & ORGAN_DEAD))
+ user.show_message("Subject's heart is necrotic.")
+ else if(!heart)
+ user.show_message("Subject has no heart.")
+
+ if(H.getStaminaLoss())
user.show_message("Subject appears to be suffering from fatigue.")
- if(M.getCloneLoss())
- user.show_message("Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.")
- if(M.has_brain_worms())
+ if(H.getCloneLoss())
+ user.show_message("Subject appears to have [H.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.")
+ if(H.has_brain_worms())
user.show_message("Subject suffering from aberrant brain activity. Recommend further scanning.")
- else if(M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && !M.get_int_organ(/obj/item/organ/internal/brain))
- user.show_message("Subject is brain dead.")
- else if(M.getBrainLoss() >= 60)
- user.show_message("Severe brain damage detected. Subject likely to have mental retardation.")
- else if(M.getBrainLoss() >= 10)
- user.show_message("Significant brain damage detected. Subject may have had a concussion.")
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- for(var/name in H.bodyparts_by_name)
- var/obj/item/organ/external/e = H.bodyparts_by_name[name]
- if(!e)
- continue
- var/limb = e.name
- if(e.status & ORGAN_BROKEN)
- if((e.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")) && !(e.status & ORGAN_SPLINTED))
- user.show_message("Unsecured fracture in subject [limb]. Splinting recommended for transport.")
- if(e.has_infected_wound())
- user.show_message("Infected wound detected in subject [limb]. Disinfection recommended.")
-
- for(var/name in H.bodyparts_by_name)
- var/obj/item/organ/external/e = H.bodyparts_by_name[name]
- if(!e)
- continue
- if(e.status & ORGAN_BROKEN)
- user.show_message(text("Bone fractures detected. Advanced scanner required for location."), 1)
- break
- for(var/obj/item/organ/external/e in H.bodyparts)
- if(e.internal_bleeding)
- user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1)
- break
- var/blood_id = H.get_blood_id()
- if(blood_id)
- if(H.bleed_rate)
- user.show_message("Subject is bleeding!")
- var/blood_percent = round((H.blood_volume / BLOOD_VOLUME_NORMAL)*100)
- var/blood_type = H.b_type
- if(blood_id != "blood")//special blood substance
- var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
- if(R)
- blood_type = R.name
- else
- blood_type = blood_id
- if(H.blood_volume <= BLOOD_VOLUME_SAFE && H.blood_volume > BLOOD_VOLUME_OKAY)
- user.show_message("LOW blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]")
- else if(H.blood_volume <= BLOOD_VOLUME_OKAY)
- user.show_message("CRITICAL blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]")
+
+ if(H.get_int_organ(/obj/item/organ/internal/brain))
+ if(H.getBrainLoss() >= 100)
+ user.show_message("Subject is brain dead.")
+ else if(H.getBrainLoss() >= 60)
+ user.show_message("Severe brain damage detected. Subject likely to have mental retardation.")
+ else if(H.getBrainLoss() >= 10)
+ user.show_message("Significant brain damage detected. Subject may have had a concussion.")
+ else
+ user.show_message("Subject has no brain.")
+
+ for(var/name in H.bodyparts_by_name)
+ var/obj/item/organ/external/e = H.bodyparts_by_name[name]
+ if(!e)
+ continue
+ var/limb = e.name
+ if(e.status & ORGAN_BROKEN)
+ if((e.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")) && !(e.status & ORGAN_SPLINTED))
+ user.show_message("Unsecured fracture in subject [limb]. Splinting recommended for transport.")
+ if(e.has_infected_wound())
+ user.show_message("Infected wound detected in subject [limb]. Disinfection recommended.")
+
+ for(var/name in H.bodyparts_by_name)
+ var/obj/item/organ/external/e = H.bodyparts_by_name[name]
+ if(!e)
+ continue
+ if(e.status & ORGAN_BROKEN)
+ user.show_message(text("Bone fractures detected. Advanced scanner required for location."), 1)
+ break
+ for(var/obj/item/organ/external/e in H.bodyparts)
+ if(e.internal_bleeding)
+ user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1)
+ break
+ var/blood_id = H.get_blood_id()
+ if(blood_id)
+ if(H.bleed_rate)
+ user.show_message("Subject is bleeding!")
+ var/blood_percent = round((H.blood_volume / BLOOD_VOLUME_NORMAL)*100)
+ var/blood_type = H.b_type
+ if(blood_id != "blood")//special blood substance
+ var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
+ if(R)
+ blood_type = R.name
else
- user.show_message("Blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]")
-
- if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
- user.show_message("Subject suffering from heart attack: Apply defibrillator immediately.")
- user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.")
- var/implant_detect
- for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs)
- if(CI.is_robotic())
- implant_detect += "[H.name] is modified with a [CI.name].
"
- if(implant_detect)
- user.show_message("Detected cybernetic modifications:")
- user.show_message("[implant_detect]")
- if(H.gene_stability < 40)
- user.show_message("Subject's genes are quickly breaking down!")
- else if(H.gene_stability < 70)
- user.show_message("Subject's genes are showing signs of spontaneous breakdown.")
- else if(H.gene_stability < 85)
- user.show_message("Subject's genes are showing minor signs of instability.")
+ blood_type = blood_id
+ if(H.blood_volume <= BLOOD_VOLUME_SAFE && H.blood_volume > BLOOD_VOLUME_OKAY)
+ user.show_message("LOW blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]")
+ else if(H.blood_volume <= BLOOD_VOLUME_OKAY)
+ user.show_message("CRITICAL blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]")
else
- user.show_message("Subject's genes are stable.")
- src.add_fingerprint(user)
- return
+ user.show_message("Blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]")
+
+ user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.")
+ var/implant_detect
+ for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs)
+ if(CI.is_robotic())
+ implant_detect += "[H.name] is modified with a [CI.name].
"
+ if(implant_detect)
+ user.show_message("Detected cybernetic modifications:")
+ user.show_message("[implant_detect]")
+ if(H.gene_stability < 40)
+ user.show_message("Subject's genes are quickly breaking down!")
+ else if(H.gene_stability < 70)
+ user.show_message("Subject's genes are showing signs of spontaneous breakdown.")
+ else if(H.gene_stability < 85)
+ user.show_message("Subject's genes are showing minor signs of instability.")
+ else
+ user.show_message("Subject's genes are stable.")
+ add_fingerprint(user)
+
/obj/item/healthanalyzer/verb/toggle_mode()
set name = "Switch Verbosity"
@@ -275,19 +285,21 @@ REAGENT SCANNER
if(0)
to_chat(usr, "The scanner no longer shows limb damage.")
-/obj/item/healthanalyzer/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/healthupgrade))
+/obj/item/healthanalyzer/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/healthupgrade))
if(upgraded)
to_chat(user, "You have already installed an upgraded in the [src].")
else
to_chat(user, "You install the upgrade in the [src].")
overlays += "advanced"
- playsound(loc, W.usesound, 50, 1)
- upgraded = 1
- qdel(W)
+ playsound(loc, I.usesound, 50, 1)
+ upgraded = TRUE
+ qdel(I)
+ return
+ return ..()
/obj/item/healthanalyzer/advanced
- upgraded = 1
+ upgraded = TRUE
/obj/item/healthanalyzer/advanced/New()
overlays += "advanced"
@@ -834,4 +846,4 @@ REAGENT SCANNER
if(target.disabilities & NEARSIGHTED)
dat += "Retinal misalignment detected.
"
- return dat
+ return dat
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 758e30947b07c..1eecd4b6e140c 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -313,7 +313,7 @@
/obj/item/twohanded/shockpaddles/attack(mob/M, mob/user)
var/tobehealed
- var/threshold = -config.health_threshold_dead
+ var/threshold = -HEALTH_THRESHOLD_DEAD
var/mob/living/carbon/human/H = M
if(busy)
@@ -472,7 +472,7 @@
/obj/item/borg_defib/attack(mob/M, mob/user)
var/tobehealed
- var/threshold = -config.health_threshold_dead
+ var/threshold = -HEALTH_THRESHOLD_DEAD
var/mob/living/carbon/human/H = M
if(busy)
diff --git a/code/game/objects/items/weapons/storage/artistic_toolbox.dm b/code/game/objects/items/weapons/storage/artistic_toolbox.dm
index 4293c0a61674e..0d8613cce4a32 100644
--- a/code/game/objects/items/weapons/storage/artistic_toolbox.dm
+++ b/code/game/objects/items/weapons/storage/artistic_toolbox.dm
@@ -176,10 +176,6 @@
affected_mob.SetSleeping(0)
affected_mob.SetSlowed(0)
affected_mob.SetConfused(0)
- if(ishuman(affected_mob))
- var/mob/living/carbon/human/H = affected_mob
- if(H.traumatic_shock < 100)
- H.shock_stage = 0
stage = 1
switch(progenitor.hunger)
if(10 to 60)
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index c52d4db7e5bb0..abf68deb7656f 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -112,6 +112,7 @@
icon_state = "medicalbelt"
item_state = "medical"
use_item_overlays = 1
+ max_w_class = WEIGHT_CLASS_NORMAL
can_hold = list(
/obj/item/healthanalyzer,
/obj/item/dnainjector,
@@ -133,6 +134,7 @@
/obj/item/rad_laser,
/obj/item/sensor_device,
/obj/item/wrench/medical,
+ /obj/item/handheld_defibrillator
)
/obj/item/storage/belt/medical/surgery
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
index 9cbd43bf09888..a25b8d03c0057 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -70,6 +70,7 @@
new /obj/item/radio/headset/headset_med(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/defibrillator/loaded(src)
+ new /obj/item/handheld_defibrillator(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/clothing/glasses/hud/health(src)
new /obj/item/clothing/shoes/sandal/white(src)
@@ -184,6 +185,7 @@
new /obj/item/radio/headset/heads/cmo(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/defibrillator/compact/loaded(src)
+ new /obj/item/handheld_defibrillator(src)
new /obj/item/storage/belt/medical(src)
new /obj/item/flash(src)
new /obj/item/reagent_containers/hypospray/CMO(src)
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index 06b168da04274..1e0bfcae34b90 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -1,7 +1,7 @@
/mob/var/suiciding = 0
/mob/living/carbon/human/proc/do_suicide(damagetype, byitem)
- var/threshold = (config.health_threshold_crit + config.health_threshold_dead) / 2
+ var/threshold = check_death_method() ? ((HEALTH_THRESHOLD_CRIT + HEALTH_THRESHOLD_DEAD) / 2) : (HEALTH_THRESHOLD_DEAD - 50)
var/dmgamt = maxHealth - threshold
var/damage_mod = 1
diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm
index aed823b372b70..2940e810ade22 100644
--- a/code/modules/martial_arts/martial.dm
+++ b/code/modules/martial_arts/martial.dm
@@ -267,7 +267,7 @@
H.Weaken(4)
if(H.staminaloss && !H.sleeping)
var/total_health = (H.health - H.staminaloss)
- if(total_health <= config.health_threshold_crit && !H.stat)
+ if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat)
H.visible_message("[user] delivers a heavy hit to [H]'s head, knocking [H.p_them()] out cold!", \
"[user] knocks you unconscious!")
H.SetSleeping(30)
diff --git a/code/modules/mob/living/carbon/_defines.dm b/code/modules/mob/living/carbon/_defines.dm
index 483502965dad3..a5a524f86ed7b 100644
--- a/code/modules/mob/living/carbon/_defines.dm
+++ b/code/modules/mob/living/carbon/_defines.dm
@@ -1,6 +1,5 @@
-//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
-#define HUMAN_MAX_OXYLOSS 3 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it.
-#define HUMAN_CRIT_MAX_OXYLOSS ( (tickerProcess.getLastTickerTimeDuration()) / 3) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 100HP to get through, so (1/3)*last_tick_duration per second. Breaths however only happen every 4 ticks.
+//NOTE: Breathing happens once EVERY OTHER TICK.
+#define HUMAN_MAX_OXYLOSS 5 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it.
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point
diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm
index 6012a8fb7f3cd..3af2250bbbdd9 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/life.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm
@@ -46,13 +46,13 @@
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
SetSilence(0)
else //ALIVE. LIGHTS ARE ON
- if(health < config.health_threshold_dead || !get_int_organ(/obj/item/organ/internal/brain))
+ if(health < HEALTH_THRESHOLD_DEAD && check_death_method() || !get_int_organ(/obj/item/organ/internal/brain))
death()
SetSilence(0)
return 1
//UNCONSCIOUS. NO-ONE IS HOME
- if((getOxyLoss() > 50) || (config.health_threshold_crit >= health))
+ if((getOxyLoss() > 50) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method()))
if(health <= 20 && prob(1))
emote("gasp")
if(!reagents.has_reagent("epinephrine"))
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 442874937180c..bdc2ee31f779a 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
@@ -18,7 +18,7 @@
if(stat == DEAD)
//If we mostly took damage from fire
- if(fireloss > 125)
+ if(getFireLoss() > 125)
icon_state = "alien[caste]_husked"
pixel_y = 0
else
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index a4b783e08fb57..a0668db83279c 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -19,7 +19,7 @@
return 1
//UNCONSCIOUS. NO-ONE IS HOME
- if( (getOxyLoss() > 25) || (config.health_threshold_crit >= health) )
+ if((getOxyLoss() > 25) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method()))
//if( health <= 20 && prob(1) )
// spawn(0)
// emote("gasp")
diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm
index 2ac3b3c4d6bdd..d0cf06f1bf718 100644
--- a/code/modules/mob/living/carbon/brain/life.dm
+++ b/code/modules/mob/living/carbon/brain/life.dm
@@ -32,7 +32,7 @@
. = ..()
if(.)
- if(!container && (health < config.health_threshold_dead || ((world.time - timeofhostdeath) > config.revival_brain_life)))
+ if(!container && (health < HEALTH_THRESHOLD_DEAD && check_death_method() || ((world.time - timeofhostdeath) > config.revival_brain_life)))
death()
return 0
diff --git a/code/modules/mob/living/carbon/brain/update_status.dm b/code/modules/mob/living/carbon/brain/update_status.dm
index 431d1eea0c3dd..6fec51bb07b8b 100644
--- a/code/modules/mob/living/carbon/brain/update_status.dm
+++ b/code/modules/mob/living/carbon/brain/update_status.dm
@@ -3,12 +3,12 @@
return
// if(health <= min_health)
if(stat == DEAD)
- if(container && health > config.health_threshold_dead)
+ if(container && health > HEALTH_THRESHOLD_DEAD)
update_revive()
create_debug_log("revived, trigger reason: [reason]")
return
else
- if(!container || health <= config.health_threshold_dead)
+ if(!container || health <= HEALTH_THRESHOLD_DEAD && check_death_method())
// Considered "dead" without any external apparatus
death()
create_debug_log("died, trigger reason: [reason]")
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index d72e5b6e2af2c..0f1c5d91df131 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -209,7 +209,7 @@
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
add_attack_logs(M, src, "Shaked", ATKLOG_ALL)
- if(health >= config.health_threshold_crit)
+ if(health >= HEALTH_THRESHOLD_CRIT)
if(src == M && ishuman(src))
var/mob/living/carbon/human/H = src
visible_message( \
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index 5d816ed625ec3..4ecd81e13389c 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -22,9 +22,8 @@
var/wetlevel = 0 //how wet the mob is
- var/failed_last_breath = FALSE //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
var/co2overloadtime = null
var/dreaming = 0 //How many dream images we have left to send
var/nightmare = 0
- blood_volume = BLOOD_VOLUME_NORMAL
+ blood_volume = BLOOD_VOLUME_NORMAL
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 3e1c874a0671f..442d7aaf044a8 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -680,6 +680,14 @@
message = "[src] trembles."
m_type = 1
+ if("shudder", "shudders")
+ message = "[src] shudders."
+ m_type = 1
+
+ if("bshake", "bshakes")
+ message = "[src] shakes."
+ m_type = 1
+
if("sneeze", "sneezes")
if(miming)
message = "[src] sneezes."
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 5550378984aaf..09787bbf73beb 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1651,6 +1651,9 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
..()
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/human/H)
+ if(H == src)
+ to_chat(src, "You cannot perform CPR on yourself!")
+ return
if(H.stat == DEAD || (H.status_flags & FAKEDEATH))
to_chat(src, "[H.name] is dead!")
return
@@ -1662,25 +1665,29 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
return
if((head && (head.flags_cover & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted))
to_chat(src, "Remove your mask first!")
- return 0
+ return
if((H.head && (H.head.flags_cover & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags_cover & MASKCOVERSMOUTH) && !H.wear_mask.mask_adjusted))
to_chat(src, "Remove [H.p_their()] mask first!")
- return 0
- visible_message("[src] is trying to perform CPR on [H.name]!", \
- "You try to perform CPR on [H.name]!")
+ return
+ if(H.receiving_cpr) // To prevent spam stacking
+ to_chat(src, "They are already receiving CPR!")
+ return
+ visible_message("[src] is trying to perform CPR on [H.name]!", "You try to perform CPR on [H.name]!")
+ H.receiving_cpr = TRUE
if(do_mob(src, H, 40))
- if(H.health > config.health_threshold_dead && H.health <= config.health_threshold_crit)
- var/suff = min(H.getOxyLoss(), 7)
- H.adjustOxyLoss(-suff)
+ if(H.health <= HEALTH_THRESHOLD_CRIT)
+ H.adjustOxyLoss(-15)
+ H.SetLoseBreath(0)
+ H.AdjustParalysis(-1)
H.updatehealth("cpr")
- visible_message("[src] performs CPR on [H.name]!", \
- "You perform CPR on [H.name].")
+ visible_message("[src] performs CPR on [H.name]!", "You perform CPR on [H.name].")
to_chat(H, "You feel a breath of fresh air enter your lungs. It feels good.")
- to_chat(src, "Repeat at least every 7 seconds.")
+ H.receiving_cpr = FALSE
add_attack_logs(src, H, "CPRed", ATKLOG_ALL)
- return 1
+ return TRUE
else
+ H.receiving_cpr = FALSE
to_chat(src, "You need to stay still while performing CPR!")
/mob/living/carbon/human/canBeHandcuffed()
@@ -1696,7 +1703,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
return FALSE
/mob/living/carbon/human/InCritical()
- return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
+ return (health <= HEALTH_THRESHOLD_CRIT && stat == UNCONSCIOUS)
/mob/living/carbon/human/IsAdvancedToolUser()
@@ -2000,4 +2007,4 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
var/obj/item/organ/internal/lantern/O = get_int_organ(/obj/item/organ/internal/lantern)
if(O && O.glowing)
O.toggle_biolum(TRUE)
- visible_message("[src] is engulfed in shadows and fades into the darkness.", "A sense of dread washes over you as you suddenly dim dark.")
+ visible_message("[src] is engulfed in shadows and fades into the darkness.", "A sense of dread washes over you as you suddenly dim dark.")
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index b858cca130a8e..b4cb92af01e8b 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -15,7 +15,7 @@
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
//TODO: fix husking
- if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD)
+ if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD)
ChangeToHusk()
update_stat("updatehealth([reason])")
med_hud_set_health()
@@ -171,11 +171,15 @@
// Defined here solely to take species flags into account without having to recast at mob/living level.
/mob/living/carbon/human/adjustOxyLoss(amount)
+ if(NO_BREATHE in dna.species.species_traits)
+ return FALSE
if(dna.species && amount > 0)
amount = amount * dna.species.oxy_mod
. = ..()
/mob/living/carbon/human/setOxyLoss(amount)
+ if(NO_BREATHE in dna.species.species_traits)
+ return FALSE
if(dna.species && amount > 0)
amount = amount * dna.species.oxy_mod
. = ..()
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 22a9d40f6fd72..9bd463b73bc8a 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -64,6 +64,7 @@ var/global/default_martial_art = new/datum/martial_art
var/check_mutations=0 // Check mutations on next life tick
var/heartbeat = 0
+ var/receiving_cpr = FALSE
var/fire_dmi = 'icons/mob/OnFire.dmi'
var/fire_sprite = "Standing"
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 8d0261528ed31..81e4fe703d592 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -10,10 +10,8 @@
update_mutations()
check_mutations=0
- handle_shock()
handle_pain()
handle_heartbeat()
- handle_heartattack()
handle_drunk()
dna.species.handle_life(src)
@@ -141,15 +139,6 @@
if(3)
emote("drool")
- if(getBrainLoss() >= 100 && stat != DEAD) //you lapse into a coma and die without immediate aid; RIP. -Fox
- Weaken(20)
- AdjustLoseBreath(10)
- AdjustSilence(2)
-
- if(getBrainLoss() >= 120 && stat != DEAD) //they died from stupidity--literally. -Fox
- visible_message("[src] goes limp, [p_their()] facial expression utterly blank.")
- death()
-
/mob/living/carbon/human/handle_mutations_and_radiation()
for(var/datum/dna/gene/gene in dna_genes)
if(!gene.block)
@@ -242,12 +231,10 @@
var/obj/item/organ/internal/L = get_organ_slot("lungs")
if(!L || L && (L.status & ORGAN_DEAD))
- if(health >= config.health_threshold_crit)
+ if(health >= HEALTH_THRESHOLD_CRIT)
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
else if(!(NOCRITDAMAGE in dna.species.species_traits))
- adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
-
- failed_last_breath = TRUE
+ adjustOxyLoss(HUMAN_MAX_OXYLOSS)
if(dna.species)
var/datum/species/S = dna.species
@@ -270,7 +257,7 @@
// USED IN DEATHWHISPERS
/mob/living/carbon/human/proc/isInCrit()
// Health is in deep shit and we're not already dead
- return health <= 0 && stat != 2
+ return health <= HEALTH_THRESHOLD_CRIT && stat != DEAD
/mob/living/carbon/human/get_breath_from_internal(volume_needed) //making this call the parent would be far too complicated
@@ -791,6 +778,70 @@
handle_organs()
+ if(getBrainLoss() >= 120 || (health + (getOxyLoss() / 2)) <= -500)
+ visible_message("[src] goes limp, their facial expression utterly blank.")
+ death()
+ return
+
+ if(getBrainLoss() >= 100) // braindeath
+ AdjustLoseBreath(10, bound_lower = 0, bound_upper = 25)
+ Weaken(30)
+
+ if(!check_death_method())
+ if(health <= HEALTH_THRESHOLD_DEAD)
+ var/deathchance = min(99, ((getBrainLoss() * -5) + (health + (getOxyLoss() / 2))) * -0.01)
+ if(prob(deathchance))
+ death()
+ return
+
+ if(health <= HEALTH_THRESHOLD_CRIT)
+ if(prob(5))
+ emote(pick("faint", "collapse", "cry", "moan", "gasp", "shudder", "shiver"))
+ AdjustStuttering(5, bound_lower = 0, bound_upper = 5)
+ EyeBlurry(5)
+ if(prob(7))
+ AdjustConfused(2)
+ if(prob(5))
+ Paralyse(2)
+ switch(health)
+ if(-INFINITY to -100)
+ adjustOxyLoss(1)
+ if(prob(health * -0.1))
+ if(ishuman(src))
+ var/mob/living/carbon/human/H = src
+ H.set_heartattack(TRUE)
+ if(prob(health * -0.2))
+ var/datum/disease/D = new /datum/disease/critical/heart_failure
+ ForceContractDisease(D)
+ Paralyse(5)
+ if(-99 to -80)
+ adjustOxyLoss(1)
+ if(prob(4))
+ to_chat(src, "Your chest hurts...")
+ Paralyse(2)
+ var/datum/disease/D = new /datum/disease/critical/heart_failure
+ ForceContractDisease(D)
+ if(-79 to -50)
+ adjustOxyLoss(1)
+ if(prob(10))
+ var/datum/disease/D = new /datum/disease/critical/shock
+ ForceContractDisease(D)
+ if(prob(health * -0.08))
+ var/datum/disease/D = new /datum/disease/critical/heart_failure
+ ForceContractDisease(D)
+ if(prob(6))
+ to_chat(src, "You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!")
+ Weaken(3)
+ if(prob(3))
+ Paralyse(2)
+ if(-49 to 0)
+ adjustOxyLoss(1)
+ if(prob(3))
+ var/datum/disease/D = new /datum/disease/critical/shock
+ ForceContractDisease(D)
+ if(prob(5))
+ to_chat(src, "You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!")
+ Weaken(3)
else //dead
SetSilence(0)
@@ -962,7 +1013,7 @@
return
if(H.is_robotic()) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people.
- if(shock_stage >= 10 || istype(get_turf(src), /turf/space))
+ if(isinspace())
//PULSE_THREADY - maximum value for pulse, currently it 5.
//High pulse value corresponds to a fast rate of heartbeat.
//Divided by 2, otherwise it is too slow.
@@ -980,7 +1031,7 @@
if(pulse == PULSE_NONE)
return
- if(pulse >= PULSE_2FAST || shock_stage >= 10 || istype(get_turf(src), /turf/space))
+ if(pulse >= PULSE_2FAST || isinspace())
//PULSE_THREADY - maximum value for pulse, currently it 5.
//High pulse value corresponds to a fast rate of heartbeat.
//Divided by 2, otherwise it is too slow.
@@ -999,7 +1050,7 @@
*/
/mob/living/carbon/human/proc/can_heartattack()
- if(NO_BLOOD in dna.species.species_traits)
+ if((NO_BLOOD in dna.species.species_traits) && !dna.species.forced_heartattack)
return FALSE
if(NO_INTORGANS in dna.species.species_traits)
return FALSE
@@ -1026,16 +1077,19 @@
heart.beating = !status
-/mob/living/carbon/human/proc/handle_heartattack()
+/mob/living/carbon/human/handle_heartattack()
if(!can_heartattack() || !undergoing_cardiac_arrest() || reagents.has_reagent("corazone"))
return
- AdjustLoseBreath(2, bound_lower = 0, bound_upper = 3)
- adjustOxyLoss(5)
- Paralyse(4)
- adjustBruteLoss(2)
+ if(getOxyLoss())
+ adjustBrainLoss(3)
+ else if(prob(10))
+ adjustBrainLoss(1)
+ Weaken(5)
+ AdjustLoseBreath(20, bound_lower = 0, bound_upper = 25)
+ adjustOxyLoss(20)
// Need this in species.
//#undef HUMAN_MAX_OXYLOSS
-//#undef HUMAN_CRIT_MAX_OXYLOSS
+//#undef HUMAN_CRIT_MAX_OXYLOSS
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index ff8083f80937c..1be6fc60a2572 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -91,7 +91,7 @@
var/obj/item/organ/internal/L = get_organ_slot("lungs")
if((breathes && !L) || breathes && L && (L.status & ORGAN_DEAD))
return FALSE
- if(oxyloss > 10 || losebreath >= 4)
+ if(getOxyLoss() > 10 || losebreath >= 4)
emote("gasp")
return FALSE
if(mind)
diff --git a/code/modules/mob/living/carbon/human/shock.dm b/code/modules/mob/living/carbon/human/shock.dm
deleted file mode 100644
index e2d5dd79cec55..0000000000000
--- a/code/modules/mob/living/carbon/human/shock.dm
+++ /dev/null
@@ -1,75 +0,0 @@
-/mob/living/carbon/human/var/traumatic_shock = 0
-/mob/living/carbon/human/var/shock_stage = 0
-
-// proc to find out in how much pain the mob is at the moment
-/mob/living/carbon/human/proc/updateshock()
- traumatic_shock = getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()
-
- // broken or ripped off organs will add quite a bit of pain
- for(var/thing in bodyparts)
- var/obj/item/organ/external/BP = thing
- if(BP.status & ORGAN_BROKEN && !(BP.status & ORGAN_SPLINTED) || BP.open)
- traumatic_shock += 15
-
- if(reagents)
- for(var/datum/reagent/R in reagents.reagent_list)
- if(R.shock_reduction)
- traumatic_shock = max(0, traumatic_shock - R.shock_reduction) // now you too can varedit cyanide to reduce shock by 1000 - Iamgoofball
- if(drunk)
- traumatic_shock = max(0, traumatic_shock - 10)
-
- return traumatic_shock
-
-/mob/living/carbon/human/proc/handle_shock()
- if(status_flags & GODMODE) //godmode
- return
- if(NO_PAIN in dna.species.species_traits)
- return
-
- updateshock()
-
- if(health <= config.health_threshold_softcrit)// health 0 makes you immediately collapse
- shock_stage = max(shock_stage, 61)
-
- if(traumatic_shock >= 100)
- shock_stage += 1
- else
- shock_stage = min(shock_stage, 160)
- shock_stage = max(shock_stage-1, 0)
- return
-
- if(shock_stage == 10)
- to_chat(src, ""+pick("It hurts so much!", "You really need some painkillers..", "Dear god, the pain!"))
-
- if(shock_stage >= 30)
- if(shock_stage == 30)
- custom_emote(1,"is having trouble keeping [p_their()] eyes open.")
- EyeBlurry(2)
- Stuttering(5)
-
- if(shock_stage == 40)
- to_chat(src, ""+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!"))
-
- if(shock_stage >=60)
- if(shock_stage == 60)
- custom_emote(1,"falls limp.")
- if(prob(2))
- to_chat(src, ""+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!"))
- Weaken(20)
-
- if(shock_stage >= 80)
- if(prob(5))
- to_chat(src, ""+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!"))
- Weaken(20)
-
- if(shock_stage >= 120)
- if(prob(2))
- to_chat(src, ""+pick("You black out!", "You feel like you could die any moment now.", "You're about to lose consciousness."))
- Paralyse(5)
-
- if(shock_stage == 150)
- custom_emote(1,"can no longer stand, collapsing!")
- Weaken(20)
-
- if(shock_stage >= 150)
- Weaken(20)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 1335c8e2d5787..e9a88fdb0333a 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -91,6 +91,8 @@
var/is_small
var/show_ssd = 1
+ var/forced_heartattack = FALSE //Some species have blood, but we still want them to have heart attacks
+ var/dies_at_threshold = FALSE // Do they die or get knocked out at specific thresholds, or do they go through complex crit?
var/can_revive_by_healing // Determines whether or not this species can be revived by simply healing them
var/has_gender = TRUE
var/blacklisted = FALSE
@@ -255,8 +257,6 @@
. += (health_deficiency / 75)
else
. += (health_deficiency / 25)
- if(H.shock_stage >= 10)
- . += 3
. += 2 * H.stance_damage //damaged/missing feet or legs is slow
if((hungry >= 70) && !flight)
@@ -298,11 +298,8 @@
// (Slime People changing color based on the reagents they consume)
/datum/species/proc/handle_life(mob/living/carbon/human/H)
if((NO_BREATHE in species_traits) || (BREATHLESS in H.mutations))
- H.setOxyLoss(0)
- H.SetLoseBreath(0)
-
var/takes_crit_damage = (!(NOCRITDAMAGE in species_traits))
- if((H.health <= config.health_threshold_crit) && takes_crit_damage)
+ if((H.health <= HEALTH_THRESHOLD_CRIT) && takes_crit_damage)
H.adjustBruteLoss(1)
return
@@ -315,7 +312,7 @@
/datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(attacker_style && attacker_style.help_act(user, target))//adminfu only...
return TRUE
- if(target.health >= config.health_threshold_crit && !(target.status_flags & FAKEDEATH))
+ if(target.health >= HEALTH_THRESHOLD_CRIT && !(target.status_flags & FAKEDEATH))
target.help_shake_act(user)
return TRUE
else
@@ -539,7 +536,7 @@
return FALSE
/datum/species/proc/get_perceived_trauma(mob/living/carbon/human/H)
- return 100 - ((NO_PAIN in species_traits) ? 0 : H.traumatic_shock) - H.getStaminaLoss()
+ return H.health - H.getStaminaLoss()
/datum/species/proc/handle_hud_icons(mob/living/carbon/human/H)
if(!H.client)
diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm
index cf1492e84080e..64c5a4aa0b3a3 100644
--- a/code/modules/mob/living/carbon/human/species/abductor.dm
+++ b/code/modules/mob/living/carbon/human/species/abductor.dm
@@ -16,8 +16,7 @@
)
species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_EXAMINE)
-
- oxy_mod = 0
+ dies_at_threshold = TRUE
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
dietflags = DIET_OMNI
diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm
index 82def809a4b8a..bccbeb6c5a783 100644
--- a/code/modules/mob/living/carbon/human/species/diona.dm
+++ b/code/modules/mob/living/carbon/human/species/diona.dm
@@ -32,6 +32,7 @@
water and other radiation."
species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN)
+ dies_at_threshold = TRUE
clothing_flags = HAS_SOCKS
default_hair_colour = "#000000"
has_gender = FALSE
@@ -39,8 +40,6 @@
taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE
skinned_type = /obj/item/stack/sheet/wood
- oxy_mod = 0
-
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
blood_color = "#004400"
flesh_color = "#907E4A"
diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm
index 032af8ea3b90f..45637fcfa6686 100644
--- a/code/modules/mob/living/carbon/human/species/golem.dm
+++ b/code/modules/mob/living/carbon/human/species/golem.dm
@@ -6,10 +6,10 @@
deform = 'icons/mob/human_races/r_golem.dmi'
species_traits = list(NO_BREATHE, NO_BLOOD, NO_PAIN, RADIMMUNE, VIRUSIMMUNE, NOGUNS)
+ dies_at_threshold = TRUE
brute_mod = 0.45 //55% damage reduction
burn_mod = 0.45
tox_mod = 0.45
- oxy_mod = 0
dietflags = DIET_OMNI //golems can eat anything because they are magic or something
reagent_tag = PROCESS_ORG
diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm
index 88ed0a626cb8b..4f5a65c82a224 100644
--- a/code/modules/mob/living/carbon/human/species/machine.dm
+++ b/code/modules/mob/living/carbon/human/species/machine.dm
@@ -19,7 +19,6 @@
burn_mod = 2.28 // So they take 50% extra damage from brute/burn overall
tox_mod = 0
clone_mod = 0
- oxy_mod = 0
death_message = "gives one shrill beep before falling limp, their monitor flashing blue before completely shutting off..."
species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_INTORGANS, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING)
@@ -36,6 +35,7 @@
//Default styles for created mobs.
default_hair = "Blue IPC Screen"
+ dies_at_threshold = TRUE
can_revive_by_healing = 1
has_gender = FALSE
reagent_tag = PROCESS_SYN
diff --git a/code/modules/mob/living/carbon/human/species/nucleation.dm b/code/modules/mob/living/carbon/human/species/nucleation.dm
index 21d8a5c0012f7..fe8a558701725 100644
--- a/code/modules/mob/living/carbon/human/species/nucleation.dm
+++ b/code/modules/mob/living/carbon/human/species/nucleation.dm
@@ -13,8 +13,8 @@
language = "Sol Common"
burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores
brute_mod = 2 // damn, double wham, double dam
- oxy_mod = 0
species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_SCAN, RADIMMUNE)
+ dies_at_threshold = TRUE
dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet
//Default styles for created mobs.
diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm
index a8fd532a3f1d7..ba249edb5a8da 100644
--- a/code/modules/mob/living/carbon/human/species/plasmaman.dm
+++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm
@@ -7,6 +7,7 @@
//language = "Clatter"
species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING)
+ forced_heartattack = TRUE // Plasmamen have no blood, but they should still get heart-attacks
skinned_type = /obj/item/stack/sheet/mineral/plasma // We're low on plasma, R&D! *eyes plasmaman co-worker intently*
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm
index df1ecd6148459..fb7fd2ebda138 100644
--- a/code/modules/mob/living/carbon/human/species/shadow.dm
+++ b/code/modules/mob/living/carbon/human/species/shadow.dm
@@ -18,8 +18,7 @@
)
species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE)
-
- oxy_mod = 0
+ dies_at_threshold = TRUE
dietflags = DIET_OMNI //the mutation process allowed you to now digest all foods regardless of initial race
reagent_tag = PROCESS_ORG
diff --git a/code/modules/mob/living/carbon/human/species/shadowling.dm b/code/modules/mob/living/carbon/human/species/shadowling.dm
index 1ce7b5cd0e04c..f65aedb530bfa 100644
--- a/code/modules/mob/living/carbon/human/species/shadowling.dm
+++ b/code/modules/mob/living/carbon/human/species/shadowling.dm
@@ -11,7 +11,6 @@
species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NOGUNS, NO_EXAMINE) //Can't use guns due to muzzle flash
burn_mod = 1.5 //1.5x burn damage, 2x is excessive
- oxy_mod = 0
heatmod = 1.5
silent_steps = 1
@@ -63,7 +62,6 @@
species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NO_EXAMINE)
burn_mod = 1.1
- oxy_mod = 0
heatmod = 1.1
/datum/species/shadow/ling/lesser/handle_life(mob/living/carbon/human/H)
diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm
index 6a2b74fb6717e..50920798d706f 100644
--- a/code/modules/mob/living/carbon/human/species/skeleton.dm
+++ b/code/modules/mob/living/carbon/human/species/skeleton.dm
@@ -11,10 +11,9 @@
flesh_color = "#E6E6C6"
species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE)
+ dies_at_threshold = TRUE
skinned_type = /obj/item/stack/sheet/bone
- oxy_mod = 0
-
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm
index 5631f600afc69..b33ebc1f0482e 100644
--- a/code/modules/mob/living/carbon/human/species/slime.dm
+++ b/code/modules/mob/living/carbon/human/species/slime.dm
@@ -20,13 +20,13 @@
cold_level_3 = 200
coldmod = 3
- oxy_mod = 0
brain_mod = 2.5
male_cough_sounds = list('sound/effects/slime_squish.ogg')
female_cough_sounds = list('sound/effects/slime_squish.ogg')
species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_INTORGANS, NO_SCAN)
+ dies_at_threshold = TRUE
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_COLOR | NO_EYES
dietflags = DIET_CARN
@@ -83,7 +83,7 @@
H.update_body()
..()
-/datum/species/slime/can_hear() // fucking snowflakes
+/datum/species/slime/can_hear() // fucking snowflakes
. = TRUE
/datum/action/innate/slimecolor
diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm
index bc21dd1ee5ffc..fa1348984323d 100644
--- a/code/modules/mob/living/carbon/human/species/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/vox.dm
@@ -31,6 +31,7 @@
eyes = "vox_eyes_s"
species_traits = list(NO_SCAN, IS_WHITELISTED, NOTRANSSTING)
+ dies_at_threshold = TRUE
clothing_flags = HAS_SOCKS
dietflags = DIET_OMNI
bodyflags = HAS_ICON_SKIN_TONE | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_BODY_MARKINGS | HAS_TAIL_MARKINGS
diff --git a/code/modules/mob/living/carbon/human/species/wryn.dm b/code/modules/mob/living/carbon/human/species/wryn.dm
index 8c576f9e30e67..6069da28f847f 100644
--- a/code/modules/mob/living/carbon/human/species/wryn.dm
+++ b/code/modules/mob/living/carbon/human/species/wryn.dm
@@ -39,7 +39,7 @@
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
dietflags = DIET_HERB //bees feed off nectar, so bee people feed off plants too
- oxy_mod = 0
+ dies_at_threshold = TRUE
reagent_tag = PROCESS_ORG
base_color = "#704300"
diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm
index e7a6512901794..9a1c7a5bbd6f8 100644
--- a/code/modules/mob/living/carbon/human/status_procs.dm
+++ b/code/modules/mob/living/carbon/human/status_procs.dm
@@ -1,3 +1,8 @@
+/mob/living/carbon/human/SetLoseBreath(amount)
+ if(NO_BREATHE in dna.species.species_traits)
+ return FALSE
+ . = ..()
+
/mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0)
if(dna.species)
amount = amount * dna.species.stun_mod
diff --git a/code/modules/mob/living/carbon/human/update_stat.dm b/code/modules/mob/living/carbon/human/update_stat.dm
index d8c26a91964f9..5dfd98c0b63e2 100644
--- a/code/modules/mob/living/carbon/human/update_stat.dm
+++ b/code/modules/mob/living/carbon/human/update_stat.dm
@@ -15,7 +15,7 @@
if(dna.species && dna.species.can_revive_by_healing)
var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain)
if(B)
- if((health >= (config.health_threshold_dead + config.health_threshold_crit) * 0.5) && getBrainLoss()<120)
+ if((health >= (HEALTH_THRESHOLD_DEAD + HEALTH_THRESHOLD_CRIT) * 0.5) && getBrainLoss() < 120)
update_revive()
create_debug_log("revived from healing, trigger reason: [reason]")
@@ -30,4 +30,7 @@
/mob/living/carbon/human/can_hear()
. = TRUE // Fallback if we don't have a species
if(dna.species)
- . = dna.species.can_hear(src)
\ No newline at end of file
+ . = dna.species.can_hear(src)
+
+/mob/living/carbon/human/check_death_method()
+ return dna.species.dies_at_threshold
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 18e42c98d08aa..48d8137092a30 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -27,8 +27,8 @@
//Start of a breath chain, calls breathe()
/mob/living/carbon/handle_breathing(times_fired)
- if(times_fired % 4 == 2 || failed_last_breath)
- breathe() //Breathe per 4 ticks, unless suffocating
+ if(times_fired % 2 == 1)
+ breathe() //Breathe every other tick, unless suffocating
else
if(istype(loc, /obj/))
var/obj/location_as_object = loc
@@ -47,13 +47,13 @@
var/datum/gas_mixture/breath
- if(health <= config.health_threshold_crit)
+ if(health <= HEALTH_THRESHOLD_CRIT && check_death_method())
AdjustLoseBreath(1)
//Suffocate
if(losebreath > 0)
AdjustLoseBreath(-1)
- if(prob(10))
+ if(prob(75))
emote("gasp")
if(istype(loc, /obj/))
var/obj/loc_as_obj = loc
@@ -97,7 +97,6 @@
//CRIT
if(!breath || (breath.total_moles() == 0) || !lungs)
adjustOxyLoss(1)
- failed_last_breath = TRUE
throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
return FALSE
@@ -121,15 +120,12 @@
if(O2_partialpressure > 0)
var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3))
- failed_last_breath = TRUE
oxygen_used = breath.oxygen*ratio
else
adjustOxyLoss(3)
- failed_last_breath = TRUE
throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else //Enough oxygen
- failed_last_breath = FALSE
adjustOxyLoss(-5)
oxygen_used = breath.oxygen
clear_alert("not_enough_oxy")
@@ -406,35 +402,54 @@
handle_hud_icons_health_overlay()
/mob/living/carbon/proc/handle_hud_icons_health_overlay()
- if(stat == UNCONSCIOUS && health <= config.health_threshold_crit)
- var/severity = 0
- switch(health)
- if(-20 to -10) severity = 1
- if(-30 to -20) severity = 2
- if(-40 to -30) severity = 3
- if(-50 to -40) severity = 4
- if(-60 to -50) severity = 5
- if(-70 to -60) severity = 6
- if(-80 to -70) severity = 7
- if(-90 to -80) severity = 8
- if(-95 to -90) severity = 9
- if(-INFINITY to -95) severity = 10
- overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
- else if(stat == CONSCIOUS)
- clear_fullscreen("crit")
- if(oxyloss)
+ if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
+ if(check_death_method())
var/severity = 0
- switch(oxyloss)
- if(10 to 20) severity = 1
- if(20 to 25) severity = 2
- if(25 to 30) severity = 3
- if(30 to 35) severity = 4
- if(35 to 40) severity = 5
- if(40 to 45) severity = 6
- if(45 to INFINITY) severity = 7
- overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
- else
- clear_fullscreen("oxy")
+ switch(health)
+ if(-20 to -10)
+ severity = 1
+ if(-30 to -20)
+ severity = 2
+ if(-40 to -30)
+ severity = 3
+ if(-50 to -40)
+ severity = 4
+ if(-60 to -50)
+ severity = 5
+ if(-70 to -60)
+ severity = 6
+ if(-80 to -70)
+ severity = 7
+ if(-90 to -80)
+ severity = 8
+ if(-95 to -90)
+ severity = 9
+ if(-INFINITY to -95)
+ severity = 10
+ overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
+ else if(stat == CONSCIOUS)
+ if(check_death_method())
+ clear_fullscreen("crit")
+ if(getOxyLoss())
+ var/severity = 0
+ switch(getOxyLoss())
+ if(10 to 20)
+ severity = 1
+ if(20 to 25)
+ severity = 2
+ if(25 to 30)
+ severity = 3
+ if(30 to 35)
+ severity = 4
+ if(35 to 40)
+ severity = 5
+ if(40 to 45)
+ severity = 6
+ if(45 to INFINITY)
+ severity = 7
+ overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
+ else
+ clear_fullscreen("oxy")
//Fire and Brute damage overlay (BSSR)
var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp
@@ -450,4 +465,4 @@
if(85 to INFINITY) severity = 6
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
- clear_fullscreen("brute")
+ clear_fullscreen("brute")
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/carbon/slime/life.dm
index 649ec7b3f00a4..e3bfcb74431c6 100644
--- a/code/modules/mob/living/carbon/slime/life.dm
+++ b/code/modules/mob/living/carbon/slime/life.dm
@@ -174,11 +174,11 @@
else
health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
- if(health < config.health_threshold_dead && stat != 2)
+ if(health < HEALTH_THRESHOLD_DEAD && check_death_method() && stat != DEAD)
death()
return
- else if(src.health <= config.health_threshold_crit)
+ else if(src.health <= HEALTH_THRESHOLD_CRIT && check_death_method())
if(!src.reagents.has_reagent("epinephrine"))
src.adjustOxyLoss(10)
diff --git a/code/modules/mob/living/carbon/update_status.dm b/code/modules/mob/living/carbon/update_status.dm
index 22030c78f4b22..58c6e09764bd3 100644
--- a/code/modules/mob/living/carbon/update_status.dm
+++ b/code/modules/mob/living/carbon/update_status.dm
@@ -3,12 +3,12 @@
return
if(stat != DEAD)
// if(health <= min_health)
- if(health <= config.health_threshold_dead)
+ if(health <= HEALTH_THRESHOLD_DEAD && check_death_method())
death()
create_debug_log("died of damage, trigger reason: [reason]")
return
// if(paralysis || sleeping || getOxyLoss() > low_oxy_ko || (status_flags & FAKEDEATH) || health <= crit_health)
- if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
+ if(paralysis || sleeping || (check_death_method() && getOxyLoss() > 50) || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT && check_death_method())
if(stat == CONSCIOUS)
KnockOut()
create_debug_log("fell unconscious, trigger reason: [reason]")
@@ -21,7 +21,7 @@
..()
if(staminaloss)
var/total_health = (health - staminaloss)
- if(total_health <= config.health_threshold_softcrit && !stat)
+ if(total_health <= HEALTH_THRESHOLD_CRIT && !stat)
to_chat(src, "You're too exhausted to keep going...")
Weaken(5)
setStaminaLoss(health - 2)
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index 734dd556b4846..e3005292c95eb 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -104,11 +104,11 @@
/mob/living/proc/getBruteLoss()
return bruteloss
-/mob/living/proc/adjustBruteLoss(var/amount, updating_health = TRUE)
+/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_bruteloss = bruteloss
- bruteloss = min(max(bruteloss + amount, 0),(maxHealth*2))
+ bruteloss = max(bruteloss + amount, 0)
if(old_bruteloss == bruteloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
@@ -120,11 +120,13 @@
/mob/living/proc/getOxyLoss()
return oxyloss
-/mob/living/proc/adjustOxyLoss(var/amount, updating_health = TRUE)
+/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
+ if(BREATHLESS in mutations)
+ return FALSE
var/old_oxyloss = oxyloss
- oxyloss = min(max(oxyloss + amount, 0),(maxHealth*2))
+ oxyloss = max(oxyloss + amount, 0)
if(old_oxyloss == oxyloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
@@ -136,6 +138,8 @@
/mob/living/proc/setOxyLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
+ if(BREATHLESS in mutations)
+ return FALSE
var/old_oxyloss = oxyloss
oxyloss = amount
if(old_oxyloss == oxyloss)
@@ -149,11 +153,11 @@
/mob/living/proc/getToxLoss()
return toxloss
-/mob/living/proc/adjustToxLoss(var/amount, updating_health = TRUE)
+/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_toxloss = toxloss
- toxloss = min(max(toxloss + amount, 0),(maxHealth*2))
+ toxloss = max(toxloss + amount, 0)
if(old_toxloss == toxloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
@@ -162,7 +166,7 @@
if(updating_health)
updatehealth("adjustToxLoss")
-/mob/living/proc/setToxLoss(var/amount, updating_health = TRUE)
+/mob/living/proc/setToxLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_toxloss = toxloss
@@ -178,11 +182,11 @@
/mob/living/proc/getFireLoss()
return fireloss
-/mob/living/proc/adjustFireLoss(var/amount, updating_health = TRUE)
+/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_fireloss = fireloss
- fireloss = min(max(fireloss + amount, 0),(maxHealth*2))
+ fireloss = max(fireloss + amount, 0)
if(old_fireloss == fireloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
@@ -194,11 +198,11 @@
/mob/living/proc/getCloneLoss()
return cloneloss
-/mob/living/proc/adjustCloneLoss(var/amount, updating_health = TRUE)
+/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE)
if(status_flags & GODMODE)
return FALSE //godmode
var/old_cloneloss = cloneloss
- cloneloss = min(max(cloneloss + amount, 0),(maxHealth*2))
+ cloneloss = max(cloneloss + amount, 0)
if(old_cloneloss == cloneloss)
updating_health = FALSE
. = STATUS_UPDATE_NONE
@@ -207,8 +211,9 @@
if(updating_health)
updatehealth("adjustCloneLoss")
-/mob/living/proc/setCloneLoss(var/amount, updating_health = TRUE)
- if(status_flags & GODMODE) return 0 //godmode
+/mob/living/proc/setCloneLoss(amount, updating_health = TRUE)
+ if(status_flags & GODMODE)
+ return FALSE //godmode
var/old_cloneloss = cloneloss
cloneloss = amount
if(old_cloneloss == cloneloss)
@@ -235,7 +240,7 @@
if(status_flags & GODMODE)
return FALSE
var/old_stamloss = staminaloss
- staminaloss = min(max(staminaloss + amount, 0),(maxHealth*2))
+ staminaloss = max(staminaloss + amount, 0)
if(old_stamloss == staminaloss)
updating = FALSE
. = STATUS_UPDATE_NONE
@@ -300,4 +305,4 @@
updatehealth("take overall damage")
/mob/living/proc/has_organic_damage()
- return (maxHealth - health)
+ return (maxHealth - health)
\ No newline at end of file
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 66f3eec1683fa..0569c94438229 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -25,6 +25,10 @@
handle_diseases()
+ //Heart Attack, if applicable
+ if(stat != DEAD)
+ handle_heartattack()
+
//Handle temperature/pressure differences between body and environment
if(environment)
handle_environment(environment)
@@ -56,6 +60,9 @@
/mob/living/proc/handle_breathing(times_fired)
return
+/mob/living/proc/handle_heartattack()
+ return
+
/mob/living/proc/handle_mutations_and_radiation()
radiation = 0 //so radiation don't accumulate in simple animals
return
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index bf933f568d468..3c5fb59aea8e4 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -246,17 +246,18 @@
set hidden = 1
if(InCritical())
create_attack_log("[src] has ["succumbed to death"] with [round(health, 0.1)] points of health!")
- adjustOxyLoss(health - config.health_threshold_dead)
+ adjustOxyLoss(health - HEALTH_THRESHOLD_DEAD)
// super check for weird mobs, including ones that adjust hp
// we don't want to go overboard and gib them, though
for(var/i = 1 to 5)
- if(health < config.health_threshold_dead)
+ if(health < HEALTH_THRESHOLD_DEAD)
break
- take_overall_damage(max(5, health - config.health_threshold_dead), 0)
+ take_overall_damage(max(5, health - HEALTH_THRESHOLD_DEAD), 0)
+ death()
to_chat(src, "You have given up life and succumbed to death.")
/mob/living/proc/InCritical()
- return (health < 0 && health > -95.0 && stat == UNCONSCIOUS)
+ return (health < HEALTH_THRESHOLD_CRIT && health > HEALTH_THRESHOLD_DEAD && stat == UNCONSCIOUS)
/mob/living/ex_act(severity)
..()
@@ -462,7 +463,6 @@
human_mob = src
human_mob.set_heartattack(FALSE)
human_mob.restore_blood()
- human_mob.shock_stage = 0
human_mob.decaylevel = 0
human_mob.remove_all_embedded_objects()
diff --git a/code/modules/mob/living/silicon/ai/update_status.dm b/code/modules/mob/living/silicon/ai/update_status.dm
index 18a35534db838..fd001956c67a4 100644
--- a/code/modules/mob/living/silicon/ai/update_status.dm
+++ b/code/modules/mob/living/silicon/ai/update_status.dm
@@ -2,7 +2,7 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
- if(health <= config.health_threshold_dead)
+ if(health <= HEALTH_THRESHOLD_DEAD && check_death_method())
death()
create_debug_log("died of damage, trigger reason: [reason]")
return
diff --git a/code/modules/mob/living/simple_animal/hostile/hellhound.dm b/code/modules/mob/living/simple_animal/hostile/hellhound.dm
index 450f676789284..f3e110d009912 100644
--- a/code/modules/mob/living/simple_animal/hostile/hellhound.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hellhound.dm
@@ -71,7 +71,7 @@
else if(health > (maxHealth*0.25))
msgs += "It is covered in wounds!"
if(resting)
- if(bruteloss > 0 || fireloss > 0)
+ if(getBruteLoss() || getFireLoss())
msgs += "It is currently licking its wounds, regenerating the damage to its body!"
else
msgs += "It is currently resting."
@@ -79,7 +79,7 @@
/mob/living/simple_animal/hostile/hellhound/Life(seconds, times_fired)
. = ..()
- if(stat != DEAD && resting && (bruteloss > 0) || (fireloss > 0))
+ if(stat != DEAD && resting && (getBruteLoss() || getFireLoss()))
if(life_regen_cycles >= life_regen_cycle_trigger)
life_regen_cycles = 0
to_chat(src, "You lick your wounds, helping them close.")
@@ -91,7 +91,7 @@
/mob/living/simple_animal/hostile/hellhound/proc/wants_to_rest()
if(target)
return FALSE
- if(bruteloss > 0 || fireloss > 0)
+ if(getBruteLoss() || getFireLoss())
return TRUE
return FALSE
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
index 4041e95c6c7f8..74a28c58c3ff5 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
@@ -98,7 +98,7 @@
/obj/item/organ/internal/hivelord_core/on_life()
..()
- if(owner.health < config.health_threshold_crit)
+ if(owner.health < HEALTH_THRESHOLD_CRIT)
ui_action_click()
/obj/item/organ/internal/hivelord_core/afterattack(atom/target, mob/user, proximity_flag)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
index c797d51ce3beb..39c03feb928fe 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
@@ -316,12 +316,12 @@ var/global/list/ts_spiderling_list = list()
adjustToxLoss(rand(1,10))
if(regen_points < regen_points_max)
regen_points += regen_points_per_tick
- if((bruteloss > 0) || (fireloss > 0))
+ if(getBruteLoss() || getFireLoss())
if(regen_points > regen_points_per_hp)
- if(bruteloss > 0)
+ if(getBruteLoss())
adjustBruteLoss(-1)
regen_points -= regen_points_per_hp
- else if(fireloss > 0)
+ else if(getFireLoss())
adjustFireLoss(-1)
regen_points -= regen_points_per_hp
if(prob(5))
diff --git a/code/modules/mob/living/stat_states.dm b/code/modules/mob/living/stat_states.dm
index fa5530091c945..70cced62aabb1 100644
--- a/code/modules/mob/living/stat_states.dm
+++ b/code/modules/mob/living/stat_states.dm
@@ -33,7 +33,7 @@
/mob/living/proc/can_be_revived()
. = TRUE
// if(health <= min_health)
- if(health <= config.health_threshold_dead)
+ if(health <= HEALTH_THRESHOLD_DEAD)
return FALSE
// death() is used to make a mob die
@@ -71,3 +71,6 @@
spell.updateButtonIcon()
return 1
+
+/mob/living/proc/check_death_method()
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 4e5c778b7fb2a..2eea575529316 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -297,6 +297,8 @@
SetLoseBreath(max(losebreath, amount))
/mob/living/SetLoseBreath(amount)
+ if(BREATHLESS in mutations)
+ return FALSE
losebreath = max(amount, 0)
/mob/living/AdjustLoseBreath(amount, bound_lower = 0, bound_upper = INFINITY)
diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm
index daf058bb41b75..bec41f6869873 100644
--- a/code/modules/mob/living/update_status.dm
+++ b/code/modules/mob/living/update_status.dm
@@ -110,7 +110,7 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
- if(health <= config.health_threshold_dead)
+ if(health <= HEALTH_THRESHOLD_DEAD && check_death_method())
death()
create_debug_log("died of damage, trigger reason: [reason]")
else if(paralysis || status_flags & FAKEDEATH)
diff --git a/code/modules/reagents/chemistry/reagents/disease.dm b/code/modules/reagents/chemistry/reagents/disease.dm
index a9cbbe8769149..9ce636b466a8b 100644
--- a/code/modules/reagents/chemistry/reagents/disease.dm
+++ b/code/modules/reagents/chemistry/reagents/disease.dm
@@ -114,6 +114,19 @@
M.ForceContractDisease(new /datum/disease/vampire(0))
return ..()
+/datum/reagent/bacon_grease
+ name = "pure bacon grease"
+ id = "bacon_grease"
+ description = "Hook me up to an IV of that sweet, sweet stuff!"
+ reagent_state = LIQUID
+ color = "#F7E6B1"
+ can_synth = FALSE
+
+/datum/reagent/bacon_grease/on_mob_life(mob/living/carbon/M)
+ if(volume > 4.5)
+ M.ForceContractDisease(new /datum/disease/critical/heart_failure(0))
+ return ..()
+
/datum/reagent/heartworms
name = "Space heartworms"
id = "heartworms"
diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm
index c4434a92c5e72..3f21593a44e4d 100644
--- a/code/modules/reagents/chemistry/reagents/food.dm
+++ b/code/modules/reagents/chemistry/reagents/food.dm
@@ -845,10 +845,7 @@
to_chat(M, "Your chest is burning with pain!")
update_flags |= M.Stun(1, FALSE)
update_flags |= M.Weaken(1, FALSE)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(!H.undergoing_cardiac_arrest())
- H.set_heartattack(TRUE)
+ M.ForceContractDisease(new /datum/disease/critical/heart_failure(0))
return ..() | update_flags
/datum/reagent/fungus
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index 804904723eadb..df32715c846fb 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -16,13 +16,6 @@
shock_reduction = 200
taste_message = "numbness"
-/datum/reagent/medicine/hydrocodone/on_mob_life(mob/living/M)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.traumatic_shock < 100)
- H.shock_stage = 0
- return ..()
-
/datum/reagent/medicine/sterilizine
name = "Sterilizine"
id = "sterilizine"
@@ -412,10 +405,6 @@
var/update_flags = STATUS_UPDATE_NONE
if(prob(55))
update_flags |= M.adjustBruteLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.traumatic_shock < 100)
- H.shock_stage = 0
return ..() | update_flags
/datum/reagent/medicine/salbutamol
@@ -472,7 +461,7 @@
update_flags |= M.AdjustWeakened(-1, FALSE)
update_flags |= M.adjustStaminaLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE)
M.AdjustLoseBreath(-1, bound_lower = 5)
- if(M.oxyloss > 75)
+ if(M.getOxyLoss() > 75)
update_flags |= M.adjustOxyLoss(-1, FALSE)
if(M.health < 0 || M.health > 0 && prob(33))
update_flags |= M.adjustToxLoss(-1, FALSE)
@@ -547,10 +536,6 @@
if(36 to INFINITY)
M.Paralyse(15)
M.Drowsy(20)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.traumatic_shock < 100)
- H.shock_stage = 0
..()
/datum/reagent/medicine/oculine
@@ -600,7 +585,7 @@
if(prob(4))
M.emote("collapse")
M.AdjustLoseBreath(-5, bound_lower = 5)
- if(M.oxyloss > 65)
+ if(M.getOxyLoss() > 65)
update_flags |= M.adjustOxyLoss(-10*REAGENTS_EFFECT_MULTIPLIER, FALSE)
if(M.health < -25)
update_flags |= M.adjustToxLoss(-1, FALSE)
@@ -636,7 +621,7 @@
update_flags |= M.adjustBrainLoss(-1, FALSE)
holder.remove_reagent("histamine", 15)
M.AdjustLoseBreath(-1, bound_lower = 3)
- if(M.oxyloss > 35)
+ if(M.getOxyLoss() > 35)
update_flags |= M.adjustOxyLoss(-10*REAGENTS_EFFECT_MULTIPLIER, FALSE)
if(M.health < -10 && M.health > -65)
update_flags |= M.adjustToxLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE)
@@ -789,7 +774,7 @@
M.SetSlur(0)
M.AdjustDrunk(-4)
M.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 8, 0, 1)
- if(M.toxloss <= 25)
+ if(M.getToxLoss() <= 25)
update_flags |= M.adjustToxLoss(-2.0, FALSE)
return ..() | update_flags
diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm
index 0897de76566d1..b523bbafb4598 100644
--- a/code/modules/reagents/chemistry/recipes/medicine.dm
+++ b/code/modules/reagents/chemistry/recipes/medicine.dm
@@ -264,11 +264,4 @@
required_reagents = list("ethanol" = 1, "copper" = 1, "silver" = 1)
result_amount = 3
min_temp = T0C + 100
- mix_message = "The solution gently swirls with a metallic sheen."
-
-/datum/chemical_reaction/corazone
- name = "Corazone"
- id = "corazone"
- result = "corazone"
- result_amount = 3
- required_reagents = list("phenol" = 2, "lithium" = 1)
+ mix_message = "The solution gently swirls with a metallic sheen."
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm
index 3a9ee271ab558..6aeafd92cf00d 100644
--- a/code/modules/reagents/reagent_containers/bottle.dm
+++ b/code/modules/reagents/reagent_containers/bottle.dm
@@ -44,10 +44,28 @@
/obj/item/reagent_containers/glass/bottle/toxin
name = "toxin bottle"
- desc = "A small bottle of toxins. Do not drink, it is poisonous."
+ desc = "A small bottle containing toxic compounds."
icon_state = "small_bottle"
list_reagents = list("toxin" = 30)
+/obj/item/reagent_containers/glass/bottle/atropine
+ name = "atropine bottle"
+ desc = "A small bottle containing atropine, used for cardiac emergencies."
+ icon_state = "small_bottle"
+ list_reagents = list("atropine" = 30)
+
+/obj/item/reagent_containers/glass/bottle/saline
+ name = "saline-glucose bottle"
+ desc = "A small bottle containing saline-glucose solution."
+ icon_state = "small_bottle"
+ list_reagents = list("salglu_solution" = 30)
+
+/obj/item/reagent_containers/glass/bottle/salicylic
+ name = "salicylic acid bottle"
+ desc = "A small bottle containing medicine for pain and fevers."
+ icon_state = "small_bottle"
+ list_reagents = list("sal_acid" = 30)
+
/obj/item/reagent_containers/glass/bottle/cyanide
name = "cyanide bottle"
desc = "A small bottle of cyanide. Bitter almonds?"
@@ -99,25 +117,25 @@
/obj/item/reagent_containers/glass/bottle/morphine
name = "Morphine Bottle"
- desc = "A small bottle. Contains morphine."
- icon_state = "round_bottle"
+ desc = "A small bottle of morphine, a powerful painkiller."
+ icon_state = "bottle"
list_reagents = list("morphine" = 30)
/obj/item/reagent_containers/glass/bottle/ether
name = "Ether Bottle"
- desc = "A small bottle. Contains ether."
+ desc = "A small bottle of an ether, a strong anesthetic and sedative."
icon_state = "round_bottle"
list_reagents = list("ether" = 30)
/obj/item/reagent_containers/glass/bottle/charcoal
name = "Charcoal Bottle"
desc = "A small bottle. Contains charcoal."
- icon_state = "round_bottle"
+ icon_state = "wide_bottle"
list_reagents = list("charcoal" = 30)
/obj/item/reagent_containers/glass/bottle/epinephrine
name = "Epinephrine Bottle"
- desc = "A small bottle. Contains epinephrine."
+ desc = "A small bottle. Contains epinephrine - used to stabilize patients."
icon_state = "round_bottle"
list_reagents = list("epinephrine" = 30)
@@ -236,9 +254,21 @@
/obj/item/reagent_containers/glass/bottle/diphenhydramine
name = "diphenhydramine bottle"
desc = "A small bottle of diphenhydramine."
- icon_state = "bottle"
+ icon_state = "round_bottle"
list_reagents = list("diphenhydramine" = 30)
+/obj/item/reagent_containers/glass/bottle/oculine
+ name = "oculine bottle"
+ desc = "A small bottle of combined eye and ear medication."
+ icon_state = "round_bottle"
+ list_reagents = list("oculine" = 30)
+
+/obj/item/reagent_containers/glass/bottle/potassium_iodide
+ name = "potassium iodide bottle"
+ desc = "A small bottle of potassium iodide."
+ icon_state = "wide_bottle"
+ list_reagents = list("potass_iodide" = 30)
+
/obj/item/reagent_containers/glass/bottle/flu_virion
name = "Flu virion culture bottle"
desc = "A small bottle. Contains H13N1 flu virion culture in synthblood medium."
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index 78e65c825911a..54a9867be602a 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -103,7 +103,7 @@
name = "Charcoal pill"
desc = "Neutralizes many common toxins."
icon_state = "pill17"
- list_reagents = list("charcoal" = 25)
+ list_reagents = list("charcoal" = 50)
/obj/item/reagent_containers/food/pill/salicylic
name = "Salicylic Acid pill"
@@ -121,4 +121,22 @@
name = "Hydrocodone pill"
desc = "Used to treat extreme pain."
icon_state = "pill6"
- list_reagents = list("hydrocodone" = 15)
\ No newline at end of file
+ list_reagents = list("hydrocodone" = 15)
+
+/obj/item/reagent_containers/food/pill/calomel
+ name = "calomel pill"
+ desc = "Can be used to purge impurities, but is highly toxic itself."
+ icon_state = "pill3"
+ list_reagents = list("calomel" = 15)
+
+/obj/item/reagent_containers/food/pill/mutadone
+ name = "mutadone pill"
+ desc = "Used to cure genetic abnormalities."
+ icon_state = "pill18"
+ list_reagents = list("mutadone" = 20)
+
+/obj/item/reagent_containers/food/pill/mannitol
+ name = "mannitol pill"
+ desc = "Used to treat cranial swelling."
+ icon_state = "pill19"
+ list_reagents = list("mannitol" = 20)
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index e75d5292be249..e28ec4c0cffe5 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -318,6 +318,11 @@
desc = "Contains insulin - used to treat diabetes."
list_reagents = list("insulin" = 15)
+/obj/item/reagent_containers/syringe/calomel
+ name = "Syringe (calomel)"
+ desc = "Contains calomel, which be used to purge impurities, but is highly toxic itself."
+ list_reagents = list("calomel" = 15)
+
/obj/item/reagent_containers/syringe/bioterror
name = "bioterror syringe"
desc = "Contains several paralyzing reagents."
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index d5434765e3027..d945722770e50 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -52,6 +52,16 @@
build_path = /obj/item/healthupgrade
category = list("Medical")
+/datum/design/handheld_defib
+ name = "Handheld Defibrillator"
+ desc = "A smaller defibrillator only capable of treating cardiac arrest."
+ id = "handheld_defib"
+ req_tech = list("biotech" = 2, "magnets" = 3)
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 20, MAT_GLASS = 20)
+ build_path = /obj/item/handheld_defibrillator
+ category = list("Medical")
+
/datum/design/defib
name = "Defibrillator"
desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients."
diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm
index 368868770c79a..b287643901d37 100644
--- a/code/modules/response_team/ert_outfits.dm
+++ b/code/modules/response_team/ert_outfits.dm
@@ -306,7 +306,8 @@
/obj/item/roller = 1,
/obj/item/storage/pill_bottle/ert = 1,
/obj/item/flashlight = 1,
- /obj/item/healthupgrade = 1
+ /obj/item/healthupgrade = 1,
+ /obj/item/handheld_defibrillator = 1
)
/datum/outfit/job/centcom/response_team/medic/red
@@ -335,7 +336,8 @@
/obj/item/roller = 1,
/obj/item/clothing/shoes/magboots = 1,
/obj/item/bodyanalyzer = 1,
- /obj/item/healthupgrade = 1
+ /obj/item/healthupgrade = 1,
+ /obj/item/handheld_defibrillator = 1
)
/datum/outfit/job/centcom/response_team/medic/gamma
@@ -357,7 +359,8 @@
/obj/item/bodyanalyzer/advanced = 1,
/obj/item/extinguisher/mini = 1,
/obj/item/roller = 1,
- /obj/item/healthanalyzer/advanced = 1
+ /obj/item/healthanalyzer/advanced = 1,
+ /obj/item/handheld_defibrillator = 1
)
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index 04626864b94fc..512de9de9e973 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -160,6 +160,7 @@
/obj/item/organ/internal/heart/cybernetic/upgraded/on_life()
if(!ishuman(owner))
return
+
if(!(status & ORGAN_DEAD) && !attempted_restart && !beating)
to_chat(owner, "Your [name] detects a cardiac event and attempts to return to its normal rhythm!")
if(prob(20) && emagged)
@@ -180,6 +181,28 @@
addtimer(CALLBACK(src, .proc/recharge), 300)
addtimer(CALLBACK(src, .proc/message_to_owner, owner, "Your [name] fails to return to its normal rhythm!"), 30)
+ if(!(status & ORGAN_DEAD) && !attempted_restart && owner.HasDisease(new /datum/disease/critical/heart_failure(0)))
+ to_chat(owner, "Your [name] detects a cardiac event and attempts to return to its normal rhythm!")
+ if(prob(40) && emagged)
+ attempted_restart = TRUE
+ for(var/datum/disease/critical/heart_failure/HF in owner.viruses)
+ HF.cure()
+ addtimer(CALLBACK(src, .proc/message_to_owner, owner, "Your [name] returns to its normal rhythm!"), 30)
+ addtimer(CALLBACK(src, .proc/recharge), 200)
+ else if(prob(25))
+ attempted_restart = TRUE
+ for(var/datum/disease/critical/heart_failure/HF in owner.viruses)
+ HF.cure()
+ addtimer(CALLBACK(src, .proc/message_to_owner, owner, "Your [name] returns to its normal rhythm!"), 30)
+ addtimer(CALLBACK(src, .proc/recharge), 200)
+ else
+ attempted_restart = TRUE
+ if(emagged)
+ addtimer(CALLBACK(src, .proc/recharge), 200)
+ else
+ addtimer(CALLBACK(src, .proc/recharge), 300)
+ addtimer(CALLBACK(src, .proc/message_to_owner, owner, "Your [name] fails to return to its normal rhythm!"), 30)
+
if(!(status & ORGAN_DEAD))
var/boost = emagged ? 2 : 1
owner.AdjustDrowsy(-4 * boost)
@@ -230,7 +253,7 @@
owner.adjustFireLoss(numHigh)
if(prob(numMid))
to_chat(owner, "Your [name] lurches awkwardly!")
- Stop()
+ owner.ForceContractDisease(new /datum/disease/critical/heart_failure(0))
if(prob(numMid))
to_chat(owner, "Your [name] stops beating!")
Stop()
@@ -246,4 +269,4 @@
owner.adjustFireLoss(numMid)
if(prob(numLow))
to_chat(owner, "Your [name] lurches awkwardly!")
- Stop()
\ No newline at end of file
+ owner.ForceContractDisease(new /datum/disease/critical/heart_failure(0))
\ No newline at end of file
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index 3026da6f66ae4..47fa74969d00a 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -19,20 +19,16 @@
var/safe_toxins_max = 0.05
var/SA_para_min = 1 //Sleeping agent
var/SA_sleep_min = 5 //Sleeping agent
- var/gas_toxicity_multiplier = 100
- var/oxy_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
- var/oxy_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
+
var/oxy_damage_type = OXY
- var/nitro_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
- var/nitro_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
+ var/oxy_breath_dam_multiplier = 1
var/nitro_damage_type = OXY
- var/co2_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
- var/co2_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
+ var/nitro_breath_dam_multiplier = 1
var/co2_damage_type = OXY
- var/tox_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
- var/tox_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
+ var/co2_breath_dam_multiplier = 1
var/tox_damage_type = TOX
+ var/tox_breath_dam_multiplier = 1
var/cold_message = "your face freezing and an icicle forming"
var/cold_level_1_threshold = 260
@@ -88,12 +84,11 @@
return
if(!breath || (breath.total_moles() == 0))
- if(H.health >= config.health_threshold_crit)
- H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
- else if(!(NOCRITDAMAGE in H.dna.species.species_traits))
- H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
+ if(isspaceturf(loc))
+ H.adjustOxyLoss(10)
+ else
+ H.adjustOxyLoss(5)
- H.failed_last_breath = TRUE
if(safe_oxygen_min)
H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else if(safe_toxins_min)
@@ -104,6 +99,10 @@
H.throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro)
return FALSE
+
+ if(H.health < HEALTH_THRESHOLD_CRIT)
+ return FALSE
+
var/gas_breathed = 0
//Partial pressures in our breath
@@ -118,8 +117,8 @@
//Too much oxygen! //Yes, some species may not like it.
if(safe_oxygen_max)
if(O2_pp > safe_oxygen_max)
- var/ratio = (breath.oxygen/safe_oxygen_max) * gas_toxicity_multiplier
- H.apply_damage_type(Clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
+ var/ratio = breath.oxygen/safe_oxygen_max
+ H.apply_damage_type(ratio * 325 * oxy_breath_dam_multiplier, oxy_damage_type)
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
else
H.clear_alert("too_much_oxy")
@@ -130,8 +129,7 @@
gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath.oxygen)
H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else
- H.failed_last_breath = FALSE
- H.adjustOxyLoss(-5)
+ H.adjustOxyLoss(-HUMAN_MAX_OXYLOSS)
gas_breathed = breath.oxygen
H.clear_alert("not_enough_oxy")
@@ -145,8 +143,8 @@
//Too much nitrogen!
if(safe_nitro_max)
if(N2_pp > safe_nitro_max)
- var/ratio = (breath.nitrogen/safe_nitro_max) * gas_toxicity_multiplier
- H.apply_damage_type(Clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type)
+ var/ratio = breath.nitrogen/safe_nitro_max
+ H.apply_damage_type(ratio * 325 * nitro_breath_dam_multiplier, nitro_damage_type)
H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro)
else
H.clear_alert("too_much_nitro")
@@ -157,8 +155,7 @@
gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.nitrogen)
H.throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro)
else
- H.failed_last_breath = FALSE
- H.adjustOxyLoss(-5)
+ H.adjustOxyLoss(-HUMAN_MAX_OXYLOSS)
gas_breathed = breath.nitrogen
H.clear_alert("not_enough_nitro")
@@ -176,9 +173,9 @@
H.co2overloadtime = world.time
else if(world.time - H.co2overloadtime > 120)
H.Paralyse(3)
- H.apply_damage_type(3, co2_damage_type) // Lets hurt em a little, let them know we mean business
+ H.apply_damage_type(HUMAN_MAX_OXYLOSS * co2_breath_dam_multiplier, co2_damage_type) // Lets hurt em a little, let them know we mean business
if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
- H.apply_damage_type(8, co2_damage_type)
+ H.apply_damage_type(15 * co2_breath_dam_multiplier, co2_damage_type)
H.throw_alert("too_much_co2", /obj/screen/alert/too_much_co2)
if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
H.emote("cough")
@@ -193,8 +190,7 @@
gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath.carbon_dioxide)
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else
- H.failed_last_breath = FALSE
- H.adjustOxyLoss(-5)
+ H.adjustOxyLoss(-HUMAN_MAX_OXYLOSS)
gas_breathed = breath.carbon_dioxide
H.clear_alert("not_enough_co2")
@@ -209,8 +205,8 @@
//Too much toxins!
if(safe_toxins_max)
if(Toxins_pp > safe_toxins_max)
- var/ratio = (breath.toxins/safe_toxins_max) * gas_toxicity_multiplier
- H.apply_damage_type(Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type)
+ var/ratio = breath.toxins/safe_toxins_max
+ H.apply_damage_type(ratio * 325 * tox_breath_dam_multiplier, tox_damage_type)
H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
H.clear_alert("too_much_tox")
@@ -222,8 +218,7 @@
gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath.toxins)
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else
- H.failed_last_breath = FALSE
- H.adjustOxyLoss(-5)
+ H.adjustOxyLoss(-HUMAN_MAX_OXYLOSS)
gas_breathed = breath.toxins
H.clear_alert("not_enough_tox")
@@ -261,11 +256,9 @@
if(breath_pp > 0)
var/ratio = safe_breath_min/breath_pp
H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!
- H.failed_last_breath = TRUE
. = true_pp*ratio/6
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
- H.failed_last_breath = TRUE
/obj/item/organ/internal/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures
@@ -332,6 +325,7 @@
safe_oxygen_max = 0.05 //This is toxic to us
safe_nitro_min = 16 //We breathe THIS!
oxy_damage_type = TOX //And it poisons us
+ oxy_breath_dam_multiplier = 0.16
/obj/item/organ/internal/lungs/drask
icon = 'icons/obj/species_organs/drask.dmi'
@@ -341,7 +335,7 @@
cold_level_1_damage = -COLD_GAS_DAMAGE_LEVEL_1 //They heal when the air is cold
cold_level_2_damage = -COLD_GAS_DAMAGE_LEVEL_2
cold_level_3_damage = -COLD_GAS_DAMAGE_LEVEL_3
- cold_damage_types = list(BRUTE = 1, BURN = 0.5)
+ cold_damage_types = list(BRUTE = 0.5, BURN = 0.25)
/obj/item/organ/internal/lungs/cybernetic
name = "cybernetic lungs"
diff --git a/config/example/game_options.txt b/config/example/game_options.txt
index 8a477dd66103d..f934ba87b2b75 100644
--- a/config/example/game_options.txt
+++ b/config/example/game_options.txt
@@ -1,10 +1,4 @@
### HEALTH ###
-## level of health at which a mob becomes unconscious (crit)
-HEALTH_THRESHOLD_CRIT -50
-
-## level of health at which a mob becomes dead
-HEALTH_THRESHOLD_DEAD -100
-
## Determines whether bones can be broken through excessive damage to the organ
## 0 means bones can't break, 1 means they can
BONES_CAN_BREAK 1
diff --git a/icons/goonstation/mob/inhands/items_lefthand.dmi b/icons/goonstation/mob/inhands/items_lefthand.dmi
index 042c15f279bee..cb8d5d6628475 100644
Binary files a/icons/goonstation/mob/inhands/items_lefthand.dmi and b/icons/goonstation/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/goonstation/mob/inhands/items_righthand.dmi b/icons/goonstation/mob/inhands/items_righthand.dmi
index 051f205bac764..1698af9855ef2 100644
Binary files a/icons/goonstation/mob/inhands/items_righthand.dmi and b/icons/goonstation/mob/inhands/items_righthand.dmi differ
diff --git a/icons/goonstation/objects/objects.dmi b/icons/goonstation/objects/objects.dmi
index 8dadb400668cc..99ddeac3d1022 100644
Binary files a/icons/goonstation/objects/objects.dmi and b/icons/goonstation/objects/objects.dmi differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index f8f6ea63db1a1..68ebe9f6e9156 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 3efddb08c4b02..fe0964994275c 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 4f9c776cc996a..faf1b5b937bf8 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -278,6 +278,7 @@
#include "code\datums\diseases\brainrot.dm"
#include "code\datums\diseases\cold.dm"
#include "code\datums\diseases\cold9.dm"
+#include "code\datums\diseases\critical.dm"
#include "code\datums\diseases\fake_gbs.dm"
#include "code\datums\diseases\flu.dm"
#include "code\datums\diseases\fluspanish.dm"
@@ -830,6 +831,7 @@
#include "code\game\objects\items\devices\flash.dm"
#include "code\game\objects\items\devices\flashlight.dm"
#include "code\game\objects\items\devices\floor_painter.dm"
+#include "code\game\objects\items\devices\handheld_defib.dm"
#include "code\game\objects\items\devices\instruments.dm"
#include "code\game\objects\items\devices\laserpointer.dm"
#include "code\game\objects\items\devices\lightreplacer.dm"
@@ -1734,7 +1736,6 @@
#include "code\modules\mob\living\carbon\human\logout.dm"
#include "code\modules\mob\living\carbon\human\npcs.dm"
#include "code\modules\mob\living\carbon\human\say.dm"
-#include "code\modules\mob\living\carbon\human\shock.dm"
#include "code\modules\mob\living\carbon\human\status_procs.dm"
#include "code\modules\mob\living\carbon\human\update_icons.dm"
#include "code\modules\mob\living\carbon\human\update_stat.dm"
diff --git a/strings/chemistry_tools.json b/strings/chemistry_tools.json
index 4a079102a6906..5bf45fc6e5827 100644
--- a/strings/chemistry_tools.json
+++ b/strings/chemistry_tools.json
@@ -468,6 +468,7 @@
"prions",
"spidereggs",
"concentrated_initro",
- "heartworms"
+ "heartworms",
+ "bacon_grease"
]
}