diff --git a/code/modules/organs/internal/_internal.dm b/code/modules/organs/internal/_internal.dm
index 024c9e86615..4318d875160 100644
--- a/code/modules/organs/internal/_internal.dm
+++ b/code/modules/organs/internal/_internal.dm
@@ -15,6 +15,9 @@
var/active_emissive = FALSE
var/list/possible_modifications = list("Normal","Assisted","Mechanical") //this is used in the character setup
+ /// The amount all organs heal themselves by per second when not being affected by chems.
+ var/organ_self_heal_per_second = 0.2
+
min_broken_damage = 10 //Internal organs are frail, man.
/obj/item/organ/internal/Destroy()
@@ -145,8 +148,17 @@
/obj/item/organ/internal/process(seconds_per_tick)
..()
- if(istype(owner) && (toxin_type in owner.chem_effects))
+ if(!owner)
+ return
+
+ if(owner.stasis_value > 0)
+ // Putting a body in stasis will simultaneously slow down the rate at which organs die
+ // while also slowing down the rate at which they are healed.
+ seconds_per_tick /= owner.stasis_value
+
+ if(toxin_type in owner.chem_effects)
take_damage(owner.chem_effects[toxin_type] * seconds_per_tick)
+
handle_regeneration(seconds_per_tick)
tick_surge_damage() //Yes, this is intentional.
@@ -155,7 +167,7 @@
if(!damage || BP_IS_ROBOTIC(src) || !istype(owner) || owner.is_asystole() || (owner.chem_effects[CE_TOXIN] || (toxin_type in owner.chem_effects)))
return FALSE
- var/repair_modifier = owner.chem_effects[CE_ORGANREPAIR] || 0.1
+ var/repair_modifier = owner.chem_effects[CE_ORGANREPAIR] || organ_self_heal_per_second
if(damage < repair_modifier*max_damage)
- heal_damage(repair_modifier)
+ heal_damage(repair_modifier * seconds_per_tick)
return TRUE // regeneration is allowed
diff --git a/code/modules/organs/internal/appendix.dm b/code/modules/organs/internal/appendix.dm
index 0846b8ed391..62999b8f36e 100644
--- a/code/modules/organs/internal/appendix.dm
+++ b/code/modules/organs/internal/appendix.dm
@@ -4,39 +4,62 @@
parent_organ = BP_GROIN
organ_tag = BP_APPENDIX
possible_modifications = list ("Normal","Removed")
+
+ /**
+ * The amount of seconds that have passed since starting an appendicitis event.
+ * This number is set initially to 1 by the event, and increments by 1 each real life second.
+ * While its at 0, no appendix calculations are performed.
+ */
var/inflamed = 0
+ /// The amount of pain to take per second while in stage 1 of appendicitis.
+ var/stage_one_pain_per_second = 1
+
+ /// The amount of pain to take per second while in stage 2 of appendicitis.
+ var/stage_two_pain_per_second = 1.5
+
+ /// The amount of damage an appendix takes per second while in stage 2 of appendicitis.
+ var/stage_two_organ_damage_per_second = 0.006
+
/obj/item/organ/internal/appendix/update_icon()
..()
if(inflamed)
icon_state = "[icon_state]inflamed"
name = "inflamed [name]"
-/obj/item/organ/internal/appendix/process()
+/obj/item/organ/internal/appendix/process(seconds_per_tick)
..()
if(!owner || !inflamed || !BP_IS_ROBOTIC(src))
return
+ if(owner.stasis_value > 0)
+ // Decrease the effective tickrate when in stasis.
+ // Basically, you die of appendicitis slower while in stasis.
+ seconds_per_tick /= owner.stasis_value
+
var/can_feel_pain = ORGAN_CAN_FEEL_PAIN(src)
- inflamed++
- if(can_feel_pain && prob(5))
- owner.custom_pain("You feel a stinging pain in your abdomen!")
- owner.visible_message("\The [owner] winces slightly.")
+ inflamed += seconds_per_tick
+
+ if(can_feel_pain)
+ if(prob(5))
+ owner.custom_pain("You feel a stinging pain in your abdomen!")
+ owner.visible_message("\The [owner] winces slightly.")
var/obj/item/organ/external/O = owner.get_organ(parent_organ)
if(O)
- O.add_pain(10)
- if(inflamed > 200 && prob(3))
- take_internal_damage(0.1)
+ O.add_pain(stage_one_pain_per_second * seconds_per_tick)
+ if(inflamed > 400)
+ take_internal_damage(stage_two_organ_damage_per_second * seconds_per_tick)
if(can_feel_pain)
- owner.visible_message("\The [owner] winces painfully.")
+ if(prob(3))
+ owner.visible_message("\The [owner] winces painfully.")
var/obj/item/organ/external/O = owner.get_organ(parent_organ)
if(O)
- O.add_pain(25)
+ O.add_pain(stage_two_pain_per_second * seconds_per_tick)
owner.adjustToxLoss(1)
- if(inflamed > 400 && prob(1))
+ if(inflamed > 800 && prob(1))
germ_level += rand(2,6)
owner.vomit()
- if(inflamed > 600 && prob(1))
+ if(inflamed > 1200 && prob(1))
if(can_feel_pain)
owner.custom_pain("You feel a stinging pain in your abdomen!")
owner.Weaken(10)
diff --git a/code/modules/organs/internal/heart.dm b/code/modules/organs/internal/heart.dm
index ff1be01e848..5cfb60622d8 100644
--- a/code/modules/organs/internal/heart.dm
+++ b/code/modules/organs/internal/heart.dm
@@ -120,6 +120,8 @@
/obj/item/organ/internal/heart/process(seconds_per_tick)
if(!owner)
return ..()
+ if(owner.stasis_value > 0) // Decrease the effective tickrate when in stasis.
+ seconds_per_tick /= owner.stasis_value
handle_pulse()
if(pulse)
if(pulse == PULSE_2FAST)
@@ -346,9 +348,7 @@
. = "[pulsesound] pulse"
-// Example heart item that has significantly higher statistics.
-// Also to be used for the Galatean Bio-augments PRs.
-// TODO: After refactoring the organ selector, make it so that this is a selectable heart type(For Galateans)
+// Galatean boosted heart
/obj/item/organ/internal/heart/boosted_heart
name = "boosted heart"
desc = "Intended for athletes, some workers, and soldiers, this improved heart increases blood flow and circulation." \
diff --git a/code/modules/organs/internal/kidneys.dm b/code/modules/organs/internal/kidneys.dm
index 9e849477628..d23e183e893 100644
--- a/code/modules/organs/internal/kidneys.dm
+++ b/code/modules/organs/internal/kidneys.dm
@@ -12,34 +12,63 @@
relative_size = 10
toxin_type = CE_NEPHROTOXIC
-/obj/item/organ/internal/kidneys/process()
+ /// The amount of toxin damage to take per second from coffee while the kidneys are bruised.
+ var/bruised_tox_damage_from_coffee = 0.2
+ /// The amount of toxin damage to take per second from coffee while the kidneys are broken.
+ var/broken_tox_damage_from_coffee = 0.6
+
+ /// Bruised kidneys will leak up to this amount of potassium into the bloodstream.
+ var/bruised_max_potassium = 5
+
+ /**
+ * Damaged kidneys leak potassium into the blood when processing any medical chems.
+ * This is the amount of reagents of potassium per second added to the bloodstream while the kidneys are bruised.
+ */
+ var/bruised_potassium_per_second = 0.1
+
+ /// Broken kidneys will leak up to this amount of potassium into the bloodstream. This number should generally be higher than the bruised value.
+ var/broken_max_potassium = 15
+
+ /**
+ * Damaged kidneys leak potassium into the blood when processing any medical chems.
+ * This is the amount of reagents of potassium per second added to the bloodstream while the kidneys are broken.
+ */
+ var/broken_potassium_per_second = 4
+
+ /// The amount of toxin damage per second taken by a body with broken kidneys.
+ var/broken_toxin_accumulation_per_second = 0.33
+
+ /// The amount of toxin damage per second taken by a body with dead kidneys.
+ var/dead_toxin_accumulation_per_second = 0.66
+
+/obj/item/organ/internal/kidneys/process(seconds_per_tick)
..()
-
if(!owner)
return
+ if(owner.stasis_value > 0) // Decrease the effective tickrate when in stasis.
+ seconds_per_tick /= owner.stasis_value
+
// Coffee is really bad for you with busted kidneys.
// This should probably be expanded in some way, but fucked if I know
// what else kidneys can process in our reagent list.
- var/singleton/reagent/drink/coffee = REAGENT_VOLUME(owner.reagents, /singleton/reagent/drink/coffee)
- if(coffee)
+ if(REAGENT_VOLUME(owner.reagents, /singleton/reagent/drink/coffee))
if(is_bruised())
- owner.adjustToxLoss(0.1)
+ owner.adjustToxLoss(bruised_tox_damage_from_coffee * seconds_per_tick)
else if(is_broken())
- owner.adjustToxLoss(0.3)
+ owner.adjustToxLoss(broken_tox_damage_from_coffee * seconds_per_tick)
if(is_bruised())
- if(prob(5) && REAGENT_VOLUME(reagents, /singleton/reagent/potassium) < 5)
- reagents.add_reagent(/singleton/reagent/potassium, REM*5)
+ if(REAGENT_VOLUME(reagents, /singleton/reagent/potassium) < bruised_max_potassium)
+ reagents.add_reagent(/singleton/reagent/potassium, bruised_potassium_per_second * seconds_per_tick)
if(is_broken())
- if(REAGENT_VOLUME(owner.reagents, /singleton/reagent/potassium) < 15)
- owner.reagents.add_reagent(/singleton/reagent/potassium, REM*2)
+ if(REAGENT_VOLUME(owner.reagents, /singleton/reagent/potassium) < broken_max_potassium)
+ owner.reagents.add_reagent(/singleton/reagent/potassium, broken_potassium_per_second * seconds_per_tick)
//If your kidneys aren't working, your body's going to have a hard time cleaning your blood.
- if(!owner.chem_effects[CE_ANTITOXIN])
- if(prob(33))
- if(is_broken())
- owner.adjustToxLoss(0.5)
- if(status & ORGAN_DEAD)
- owner.adjustToxLoss(1)
+ if(!owner.chem_effects[CE_ANTITOXIN]) // Dylovene fully prevents the toxin accumulation from kidneys.
+ if(is_broken())
+ owner.adjustToxLoss(broken_toxin_accumulation_per_second * seconds_per_tick)
+ if(status & ORGAN_DEAD)
+ owner.adjustToxLoss(dead_toxin_accumulation_per_second * seconds_per_tick)
diff --git a/code/modules/organs/internal/liver.dm b/code/modules/organs/internal/liver.dm
index fab93c1dc4c..5f4c89f2804 100644
--- a/code/modules/organs/internal/liver.dm
+++ b/code/modules/organs/internal/liver.dm
@@ -76,6 +76,9 @@
if(!owner)
return
+ if(owner.stasis_value > 0) // Decrease the effective tickrate when in stasis.
+ seconds_per_tick /= owner.stasis_value
+
if(germ_level > INFECTION_LEVEL_ONE)
owner.notify_message(SPAN_WARNING(infection_level_one_warning), 2 MINUTES)
if(germ_level > INFECTION_LEVEL_TWO && prob(1))
@@ -160,6 +163,7 @@
return TRUE
return FALSE
+// Galatean bioaugmented liver. Dramatically enhanced over a base human liver.
/obj/item/organ/internal/liver/boosted_liver
name = "boosted liver"
desc = "Designed primarily for diplomats or Galateans abroad, the boosted liver improves toxin filtering, giving a resistance to toxin damage. As a consequence, it makes it impossible for the user to get drunk."
diff --git a/code/modules/organs/internal/stomach.dm b/code/modules/organs/internal/stomach.dm
index 4df7884e64b..ad32c24333a 100644
--- a/code/modules/organs/internal/stomach.dm
+++ b/code/modules/organs/internal/stomach.dm
@@ -101,38 +101,40 @@
/obj/item/organ/internal/stomach/process()
..()
- if(owner)
- var/functioning = is_usable()
- if(damage >= min_bruised_damage && prob((damage / max_damage) * 100))
- functioning = FALSE
+ if(!owner)
+ return
- if(functioning)
- for(var/mob/living/M in contents)
- if(M.stat == DEAD)
- addtimer(CALLBACK(src, PROC_REF(digest_mob), M), 5 MINUTES, TIMER_UNIQUE)
+ var/functioning = is_usable()
+ if(damage >= min_bruised_damage && prob((damage / max_damage) * 100))
+ functioning = FALSE
- M.adjustBruteLoss(2)
- M.adjustFireLoss(2)
+ if(functioning)
+ for(var/mob/living/M in contents)
+ if(M.stat == DEAD)
+ addtimer(CALLBACK(src, PROC_REF(digest_mob), M), 5 MINUTES, TIMER_UNIQUE)
- var/digestion_product = M.get_digestion_product()
- if(digestion_product)
- ingested.add_reagent(digestion_product, rand(1,3))
+ M.adjustBruteLoss(2)
+ M.adjustFireLoss(2)
- else if(world.time >= next_cramp)
- next_cramp = world.time + rand(200,800)
- owner.custom_pain("Your stomach cramps agonizingly!",1)
+ var/digestion_product = M.get_digestion_product()
+ if(digestion_product)
+ ingested.add_reagent(digestion_product, rand(1,3))
- if(should_process_alcohol)
+ else if(world.time >= next_cramp)
+ next_cramp = world.time + rand(200,800)
+ owner.custom_pain("Your stomach cramps agonizingly!",1)
- var/alcohol_volume = REAGENT_VOLUME(ingested, /singleton/reagent/alcohol)
+ if(should_process_alcohol)
- // Alcohol counts as double volume for the purposes of vomit probability
- var/effective_volume = ingested.total_volume + alcohol_volume
+ var/alcohol_volume = REAGENT_VOLUME(ingested, /singleton/reagent/alcohol)
- // Just over the limit, the probability will be low. It rises a lot such that at double ingested it's 64% chance.
- var/vomit_probability = (effective_volume / stomach_volume) ** 6
- if(prob(vomit_probability))
- owner.vomit()
+ // Alcohol counts as double volume for the purposes of vomit probability
+ var/effective_volume = ingested.total_volume + alcohol_volume
+
+ // Just over the limit, the probability will be low. It rises a lot such that at double ingested it's 64% chance.
+ var/vomit_probability = (effective_volume / stomach_volume) ** 6
+ if(prob(vomit_probability))
+ owner.vomit()
/obj/item/organ/internal/stomach/proc/digest_mob(mob/M)
if(!QDELETED(M))
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index 6949a39c596..5ac4a26c974 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -1641,7 +1641,7 @@
/singleton/reagent/rezadone/affect_chem_effect(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
. = ..()
if(.)
- M.add_chemical_effect(CE_ORGANREPAIR, 1)
+ M.add_chemical_effect(CE_ORGANREPAIR, 2)
M.add_chemical_effect(CE_BLOODRESTORE, 15)
/singleton/reagent/rezadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
@@ -1674,7 +1674,7 @@
/singleton/reagent/sanasomnum/affect_chem_effect(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
. = ..()
if(.)
- M.add_chemical_effect(CE_ORGANREPAIR, 20)
+ M.add_chemical_effect(CE_ORGANREPAIR, 40)
M.add_chemical_effect(CE_BLOODRESTORE, 15)
M.add_chemical_effect(CE_BLOODCLOT, 15)
M.add_chemical_effect(CE_BRAIN_REGEN, 20)
diff --git a/html/changelogs/hellfirejag-organ-stasis-rework.yml b/html/changelogs/hellfirejag-organ-stasis-rework.yml
new file mode 100644
index 00000000000..073e5ceaab4
--- /dev/null
+++ b/html/changelogs/hellfirejag-organ-stasis-rework.yml
@@ -0,0 +1,62 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# - (fixes bugs)
+# wip
+# - (work in progress)
+# qol
+# - (quality of life)
+# soundadd
+# - (adds a sound)
+# sounddel
+# - (removes a sound)
+# rscadd
+# - (adds a feature)
+# rscdel
+# - (removes a feature)
+# imageadd
+# - (adds an image or sprite)
+# imagedel
+# - (removes an image or sprite)
+# spellcheck
+# - (fixes spelling or grammar)
+# experiment
+# - (experimental change)
+# balance
+# - (balance changes)
+# code_imp
+# - (misc internal code change)
+# refactor
+# - (refactors code)
+# config
+# - (makes a change to the config files)
+# admin
+# - (makes changes to administrator tools)
+# server
+# - (miscellaneous changes to server)
+#################################
+
+# Your name.
+author: Hellfirejag
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
+# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Organ passive healing and passive damage are both reduced by medical stasis."
+ - rscadd: "Appendicitis now progresses slower while in stasis, and is also now tick-invariant."
+ - rscadd: "Hearts now take less damage from tachycardia while in stasis."
+ - rscadd: "Bruised/Broken kidneys now have reduced effects while in stasis."
+ - rscadd: "Livers now filter toxins and booze slower while in stasis."