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" ] }