diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 35a060863e7..57594d5567c 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -189,7 +189,7 @@
var/mob/M = grab.affecting
qdel(grab)
put_mob(M)
-
+
return
/obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(var/mob/target, var/mob/user) //Allows borgs to put people into cryo without external assistance
@@ -226,6 +226,11 @@
if(occupant.bodytemperature < 225)
if(occupant.getToxLoss())
occupant.adjustToxLoss(max(-1, -20/occupant.getToxLoss()))
+ if(occupant.radiation || occupant.accumulated_rads)
+ occupant.radiation -= 25
+ occupant.accumulated_rads -= 25
+ if(occupant.bloodstr.get_reagent_amount("prussian_blue") < 2)
+ occupant.bloodstr.add_reagent("prussian_blue",5)
var/heal_brute = occupant.getBruteLoss() ? min(1, 20/occupant.getBruteLoss()) : 0
var/heal_fire = occupant.getFireLoss() ? min(1, 20/occupant.getFireLoss()) : 0
occupant.heal_organ_damage(heal_brute,heal_fire)
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 703d174bee2..44459d1b964 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -104,8 +104,9 @@
cell.use(7000/450*10)
// And clear up radiation
- if(H.radiation > 0)
- H.radiation = max(H.radiation - rand(5, 15), 0)
+ if(H.radiation > 0 || H.accumulated_rads > 0)
+ H.radiation = max(H.radiation - 25, 0)
+ H.accumulated_rads = max(H.accumulated_rads - 25, 0)
if(H.wearing_rig) // stepping into a borg charger to charge your rig and fix your shit
var/obj/item/weapon/rig/wornrig = H.get_rig()
diff --git a/code/game/objects/items/devices/scanners/health.dm b/code/game/objects/items/devices/scanners/health.dm
index 02b33bdec56..90cfb3e4aa1 100644
--- a/code/game/objects/items/devices/scanners/health.dm
+++ b/code/game/objects/items/devices/scanners/health.dm
@@ -105,17 +105,35 @@
if(M.radiation)
if(advscan >= 2 && showadvscan == 1)
var/severity = ""
- if(M.radiation >= 75)
+ if(M.radiation >= 1500)
+ severity = "Lethal"
+ else if(M.radiation >= 600)
severity = "Critical"
- else if(M.radiation >= 50)
+ else if(M.radiation >= 400)
severity = "Severe"
- else if(M.radiation >= 25)
+ else if(M.radiation >= 300)
severity = "Moderate"
- else if(M.radiation >= 1)
+ else if(M.radiation >= 100)
severity = "Low"
- dat += "[severity] levels of radiation detected. [(severity == "Critical") ? " Immediate treatment advised." : ""]
"
+ dat += "[severity] levels of acute radiation sickness detected. [round(M.radiation/50)]Gy. [(severity == "Critical" || severity == "Lethal") ? " Immediate treatment advised." : ""]
"
else
- dat += "Radiation detected.
"
+ dat += "Acute radiation sickness detected.
"
+ if(M.accumulated_rads)
+ if(advscan >= 2 && showadvscan == 1)
+ var/severity = ""
+ if(M.accumulated_rads >= 1500)
+ severity = "Critical"
+ else if(M.accumulated_rads >= 600)
+ severity = "Severe"
+ else if(M.accumulated_rads >= 400)
+ severity = "Moderate"
+ else if(M.accumulated_rads >= 300)
+ severity = "Mild"
+ else if(M.accumulated_rads >= 100)
+ severity = "Low"
+ dat += "[severity] levels of chronic radiation sickness detected. [round(M.accumulated_rads/50)]Gy.
"
+ else
+ dat += "Chronic radiation sickness detected.
"
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.reagents.total_volume)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 6e155eeba17..b70c9989465 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -248,9 +248,28 @@
to_chat(src, "Your legs won't respond properly, you fall down!")
Weaken(10)
+// RADIATION! Everyone's favorite thing in the world! So let's get some numbers down off the bat.
+// 50 rads = 1Bq. This means 1 rad = 0.02Bq.
+// However, unless I am a smoothbrained dumbo, absorbed rads are in Gy. Not Bq.
+// So let's just assume that 50 rads = 1Gy. Make life easier!
+
+// ACUTE RADIATION (The stuff that the 'radiation' variable takes care of. Remember, 50radiation=1Gy.):
+// Without care: 1-2Gy has a (0-5%) mortality chance. 2-6 (5-95%) 6-8 (95-100)% 8-30 (100%) >30 (100%)
+// With care: 1-2Gy (0-5%), 2-6 (5-50%), 6-8 (50-100%), 8-30 (99-100%) >30 (100%)
+// So let's make our thresholds based on this! 50-100, 100-300, 300-400, 400-1500, and anything above 1500!
+// In reality, however, nobody should ever go above 300 radiation, which is why the cutoff before the really bad effects start to happen being
+// 300 radiation is good. For reference: Breaking an artifact deals ~300 rads with no resistance. Getting shot with a lvl 3 PA deals 300 rads with no resistance.
+// Nobody outside of engineering should ever have to worry about being irradiated over 300 and start getting organ damage..
-/mob/living/carbon/human/handle_mutations_and_radiation()
+// CHRONIC RADIATION (The stuff that 'accumulated_rads' takes care of):
+// This is more or less for if someone was exposed for a long time to radiation or just finished being treated for extreme ARS.
+// These are meant to be annoying effects to nudge someone towards medical, but not lethal or deadly.
+// Things such as loss of taste, eye damage, dropping items in your hand, being temporaily weakened, etc. Stuff to annoy them and get them to fix their rads.
+
+// Additionally, RADIATION_SPEED_COEFFICIENT = 0.1
+
+/mob/living/carbon/human/handle_mutations_and_radiation() //Radiation rework! Now with 'accumulated_rads'
if(inStasisNow())
return
@@ -267,12 +286,15 @@
if(gene.is_active(src))
gene.OnMobLife(src)
- radiation = CLAMP(radiation,0,250)
-
+ radiation = CLAMP(radiation,0,2500) //Max of 50Gy. If you reach that...You're going to wish you were dead. You probably will be dead.
+ accumulated_rads = CLAMP(accumulated_rads,0,2500) //Max of 50Gy as well. You should never get higher than this. You will be dead before you can reach this.
+ var/obj/item/organ/internal/I = null //Used for further down below when an organ is picked.
if(!radiation)
if(species.appearance_flags & RADIATION_GLOWS)
set_light(0)
- else
+ if(accumulated_rads)
+ accumulated_rads -= RADIATION_SPEED_COEFFICIENT //Accumulated rads slowly dissipate very slowly. Get to medical to get it treated!
+ else if(((life_tick % 5 == 0) && radiation) || (radiation > 600)) //Radiation is a slow, insidious killer. Unless you get a massive dose, then the onset is sudden!
if(species.appearance_flags & RADIATION_GLOWS)
set_light(max(1,min(5,radiation/15)), max(1,min(10,radiation/25)), species.get_flesh_colour(src))
// END DOGSHIT SNOWFLAKE
@@ -299,42 +321,139 @@
return
//VOREStation Addition end: shadekin
- var/damage = 0
- radiation -= 1 * RADIATION_SPEED_COEFFICIENT
- if(radiation > 2.5 && prob(25)) // Safe for a little over 2m at the recommended maximum safe dosage of 0.05Bq
- damage = 1
+ if(reagents.has_reagent("prussian_blue")) //Prussian Blue temporarily stops radiation effects.
+ return
- if (radiation > 50)
+ var/damage = 0
+
+
+ if (radiation < 50) //Less than 1.0 Gy. No side effects.
+ radiation -= 10 * RADIATION_SPEED_COEFFICIENT
+ accumulated_rads += 10 * RADIATION_SPEED_COEFFICIENT //No escape from accumulated rads.
+
+ else if (radiation >= 50 && radiation < 100) //Equivalent of 1.0-2.0 Gy. Minimum stage you start seeing effects.
damage = 1
- radiation -= 1 * RADIATION_SPEED_COEFFICIENT
+ radiation -= 10 * RADIATION_SPEED_COEFFICIENT
+ accumulated_rads += 10 * RADIATION_SPEED_COEFFICIENT
if(!isSynthetic())
- if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT))
- radiation -= 5 * RADIATION_SPEED_COEFFICIENT
- to_chat(src, "You feel weak.")
- Weaken(3)
- if(!lying)
- emote("collapse")
+ if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && !weakened)
+ to_chat(src, "You feel exhausted.")
+ AdjustWeakened(3)
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && species.get_bodytype() == SPECIES_HUMAN) //apes go bald
if((h_style != "Bald" || f_style != "Shaved" ))
to_chat(src, "Your hair falls out.")
h_style = "Bald"
f_style = "Shaved"
update_hair()
+ if(prob(1) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //Rare chance of vomiting.
+ spawn vomit()
- if (radiation > 75)
+ else if (radiation >= 100 && radiation < 300) //Equivalent of 2.0 to 6.0 Gy. Nobody should ever be above this without extreme negligence.
damage = 3
- radiation -= 1 * RADIATION_SPEED_COEFFICIENT
+ radiation -= 30 * RADIATION_SPEED_COEFFICIENT
+ accumulated_rads += 30 * RADIATION_SPEED_COEFFICIENT
if(!isSynthetic())
if(prob(5))
take_overall_damage(0, 5 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
if(prob(1))
- to_chat(src, "You feel strange!")
adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
emote("gasp")
+ if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT))
+ spawn vomit()
+ if(prob(10) && !weakened)
+ to_chat(src, "You feel sick.")
+ AdjustWeakened(3)
- if (radiation > 150)
- damage = 6
- radiation -= 4 * RADIATION_SPEED_COEFFICIENT
+ else if (radiation >= 300 && radiation < 400) //Equivalent of 6.0 to 8.0 Gy.
+ damage = 5
+ radiation -= 50 * RADIATION_SPEED_COEFFICIENT
+ accumulated_rads += 50 * RADIATION_SPEED_COEFFICIENT
+ if(!isSynthetic())
+ if(prob(15))
+ take_overall_damage(0, 10 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
+ if(prob(2))
+ adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
+ emote("gasp")
+ if(prob(10) && prob(100 * RADIATION_SPEED_COEFFICIENT))
+ spawn vomit()
+ if(prob(15) && !weakened)
+ to_chat(src, "You feel horribly ill.")
+ AdjustWeakened(3)
+ if(prob(5) && internal_organs.len)
+ I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
+ if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage)
+ I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
+
+
+ else if (radiation >= 400 && radiation < 1500) //Equivalent of 8.0 to 30 Gy.
+ damage = 10
+ radiation -= 100 * RADIATION_SPEED_COEFFICIENT
+ accumulated_rads += 100 * RADIATION_SPEED_COEFFICIENT
+ if(!isSynthetic())
+ if(prob(25))
+ take_overall_damage(0, 15 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
+ if(prob(5))
+ I = internal_organs_by_name[O_EYES]
+ if(I)
+ if(istype(I)) I.add_autopsy_data("Radiation Burns", damage)
+ I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
+ to_chat(src, "Your eyes burn!")
+ eye_blurry += 10
+ if(prob(4))
+ adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
+ emote("gasp")
+ if(prob(25) && prob(100 * RADIATION_SPEED_COEFFICIENT))
+ spawn vomit()
+ if(prob(20) && !weakened)
+ to_chat(src, "You feel like your insides are burning!")
+ AdjustWeakened(5)
+ if(prob(5))
+ to_chat(src, "Your entire body feels like it's on fire!")
+ adjustHalLoss(5)
+ if(prob(10) && internal_organs.len)
+ I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
+ if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage)
+ I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
+
+ else if (radiation >= 1500) //Above 30Gy. You had to get absolutely blasted with rads for this.
+ damage = 30
+ radiation -= 300 * RADIATION_SPEED_COEFFICIENT
+ accumulated_rads += 300 * RADIATION_SPEED_COEFFICIENT
+
+ if(!isSynthetic())
+ take_overall_damage(0, damage * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns") //3 burn damage a tick as your body melts.
+ adjustCloneLoss(15 * RADIATION_SPEED_COEFFICIENT) //1.5 cloneloss a tick as your cells mutate and break down.
+
+ I = internal_organs_by_name[O_EYES]
+ if(I)
+ I.add_autopsy_data("Radiation Burns", damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
+ I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) //3 eye damage a tick as your eyes melt down.
+ eye_blurry += 10
+
+ if(prob(50) && prob(100 * RADIATION_SPEED_COEFFICIENT))
+ spawn vomit()
+ if(!paralysis && prob(30) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //CNS is shutting down.
+ to_chat(src, "You have a seizure!")
+ Paralyse(10)
+ make_jittery(1000)
+ if(!lying)
+ emote("collapse")
+ if(get_active_hand() && prob(15)) //CNS is shutting down.
+ to_chat(src, "Your hand won't respond properly, you drop what you're holding!")
+ drop_item()
+ if(internal_organs.len)
+ I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
+ if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
+ I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
+
+/* //Not-so-sparkledog code. TODO: Make a pref for 'special game interactions' that allows interactions that align with prefs to occur.
+ if(radiation >= 250) //Special effect stuff that occurs at certain rad levels.
+ if(prob(1) && prob(radiation/2 * RADIATION_SPEED_COEFFICIENT) && allow_spontaneous_tf) //If you've got spontaneous TF...well...
+ scramble(1, src, 3) //I tried to base this on how many rads you took and it was...Hilarious. Sparkledogs everywhere.
+ //For the most part, 3 strength will simply change colors. If you get really unlucky, it can do more TF's.
+ //Math: 250 rads = 1/800 chance
+ //500 rads = 1/400 chance chance. Etc.
+*/
if(damage)
damage *= species.radiation_mod
@@ -344,6 +463,47 @@
var/obj/item/organ/external/O = pick(organs)
if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage)
+ // Begin long-term radiation effects
+ // Loss of taste occurs at 100 (2Gy) and is handled in taste.dm
+ // These are all done one after another, so duplication is not required. Someone at 400rads will have the 100&400 effects.
+ if(!radiation && accumulated_rads >= 100 && !reagents.has_reagent("prussian_blue")) //Let's not hit them with long term effects when they're actively being hit with rads.
+ if(!isSynthetic())
+ I = internal_organs_by_name[O_EYES]
+ if(I) //Eye stuff
+ if(prob(5) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
+ to_chat(src, "Your eyes water.")
+ eye_blurry += 5
+ if(accumulated_rads > 300) // (6Gy)
+ if(prob(2) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
+ to_chat(src, "Your eyes burn.")
+ I.add_autopsy_data("Radiation Burns", 1 * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
+ I.take_damage(1 * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) //0.1 damage. Not a lot, but enough to tell you to get to medical.
+ eye_blurry += 10
+
+ if(accumulated_rads > 200) // (4Gy)
+ if(prob(5) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
+ to_chat(src, "Your feel nauseated.")
+ spawn vomit()
+ if(!weakened && prob(2) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
+ to_chat(src, "Your feel exhausted.")
+ AdjustWeakened(3)
+ if(accumulated_rads > 300) // (6Gy)
+ if(get_active_hand() && prob(15) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //CNS is shutting down.
+ to_chat(src, "Your hand won't respond properly, you drop what you're holding!")
+ drop_item()
+ if(accumulated_rads > 700) // (12Gy)
+ if(!paralysis && prob(1) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //1 in 1000 chance per tick.
+ to_chat(src, "You have a seizure!")
+ Paralyse(10)
+ make_jittery(1000)
+ if(!lying)
+ emote("collapse")
+
+ else //The synthetic effects!
+ return //Nothing for now.
+
+
+
/** breathing **/
/mob/living/carbon/human/handle_chemical_smoke(var/datum/gas_mixture/environment)
diff --git a/code/modules/mob/living/carbon/taste.dm b/code/modules/mob/living/carbon/taste.dm
index f02e7047216..150f67d955e 100644
--- a/code/modules/mob/living/carbon/taste.dm
+++ b/code/modules/mob/living/carbon/taste.dm
@@ -11,6 +11,9 @@
from.trans_to_holder(temp, amount, multiplier, 1)
var/text_output = temp.generate_taste_message(src)
+ if(accumulated_rads >= 100) //If you're irradiated, you can't taste!
+ text_output = "nothing"
+
if(text_output != last_taste_text || last_taste_time + 100 < world.time) //We dont want to spam the same message over and over again at the person. Give it a bit of a buffer.
to_chat(src, "You can taste [text_output].")//no taste means there are too many tastes and not enough flavor.
diff --git a/code/modules/mob/mob_defines_vr.dm b/code/modules/mob/mob_defines_vr.dm
index 3854620e7c1..09ada3789be 100644
--- a/code/modules/mob/mob_defines_vr.dm
+++ b/code/modules/mob/mob_defines_vr.dm
@@ -8,6 +8,7 @@
var/obj/screen/xenochimera/danger_level/xenochimera_danger_display = null
var/size_multiplier = 1 //multiplier for the mob's icon size
+ var/accumulated_rads = 0 // For radiation stuff.
/mob/drop_location()
if(temporary_form)
diff --git a/code/modules/reagents/reactions/instant/instant_vr.dm b/code/modules/reagents/reactions/instant/instant_vr.dm
index bbc6c372e4c..2172788234b 100644
--- a/code/modules/reagents/reactions/instant/instant_vr.dm
+++ b/code/modules/reagents/reactions/instant/instant_vr.dm
@@ -181,6 +181,13 @@
catalysts = list("phoron" = 5)
result_amount = 3
+/decl/chemical_reaction/instant/prussian_blue
+ name = "Prussian Blue"
+ id = "prussian_blue"
+ result = "prussian_blue"
+ required_reagents = list("carbon" = 3, "iron" = 1, "nitrogen" = 3)
+ result_amount = 7
+
///////////////////////////////////////////////////////////////////////////////////
/// Reagent colonies.
/decl/chemical_reaction/instant/meatcolony
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index cee7ed41335..8360d45c020 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -249,7 +249,7 @@
name = "purity hypo"
desc = "A refined version of the standard autoinjector, allowing greater capacity. This variant excels at \
resolving viruses, infections, radiation, and genetic maladies."
- filled_reagents = list("spaceacillin" = 9, "arithrazine" = 5, "ryetalyn" = 1)
+ filled_reagents = list("spaceacillin" = 4, "arithrazine" = 5, "prussian_blue" = 5, "ryetalyn" = 1)
/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain
name = "pain hypo"
diff --git a/code/modules/reagents/reagents/medicine.dm b/code/modules/reagents/reagents/medicine.dm
index 469b192f224..fa961b278ab 100644
--- a/code/modules/reagents/reagents/medicine.dm
+++ b/code/modules/reagents/reagents/medicine.dm
@@ -1095,6 +1095,7 @@
if(alien == IS_DIONA)
return
M.radiation = max(M.radiation - 30 * removed * M.species.chem_strength_heal, 0)
+ M.accumulated_rads = max(M.accumulated_rads - 30 * removed * M.species.chem_strength_heal, 0)
/datum/reagent/arithrazine
name = "Arithrazine"
@@ -1112,6 +1113,7 @@
if(alien == IS_DIONA)
return
M.radiation = max(M.radiation - 70 * removed * M.species.chem_strength_heal, 0)
+ M.accumulated_rads = max(M.accumulated_rads - 70 * removed * M.species.chem_strength_heal, 0)
M.adjustToxLoss(-10 * removed)
if(prob(60))
M.take_organ_damage(4 * removed, 0)
diff --git a/code/modules/reagents/reagents/medicine_vr.dm b/code/modules/reagents/reagents/medicine_vr.dm
index 55ed8b1ee2e..deab52a8dd3 100644
--- a/code/modules/reagents/reagents/medicine_vr.dm
+++ b/code/modules/reagents/reagents/medicine_vr.dm
@@ -92,3 +92,22 @@
/datum/reagent/sleevingcure/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.remove_a_modifier_of_type(/datum/modifier/resleeving_sickness)
M.remove_a_modifier_of_type(/datum/modifier/faux_resleeving_sickness)
+
+
+
+/datum/reagent/prussian_blue //We don't have iodine, so prussian blue we go.
+ name = "Prussian Blue"
+ id = "prussian_blue"
+ description = "Prussian Blue is an medication used to temporarily pause the effects of radiation poisoning to allow for treatment. Does not treat radiation sickness on its own."
+ taste_description = "salt"
+ reagent_state = SOLID
+ color = "#003153" //Blue!
+ metabolism = REM * 0.25//20 ticks to do things per unit injected. This means injecting 30u will give you 10 minutes to do what you need.
+ overdose = REAGENTS_OVERDOSE
+ scannable = 1
+
+/datum/reagent/prussian_blue/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ if(alien == IS_DIONA)
+ return
+ if(prob(10)) //Miniscule chance of removing some toxins.
+ M.adjustToxLoss(-10 * removed)
\ No newline at end of file