Radiation additions & Component (#18642)

* It begins

* Better coding practices

* No mapwide radiation glow!

* Update radiation_effects.dm

* A bit more efficient

* Theeese too

* moar

* caps

* lint

* Stops self contamiantion

* Mregen

Fixes this bug with mRegen. Also gives bruteloss the 1% heal chance.

* MAR!

* TGUI panel

* Nuclear png

Attribution not required, but being listed for posterity:
From uxwing. Icon name is "Radiation Icon SVG Vector"

* colorful

* Update nuclear.scss

* Update damage_procs.dm

* Radiation Negative Trait

* Update radiation_effects.dm

* get rid of this bad documentation

Should only EVER be registerwithparent.
This commit is contained in:
Cameron Lennox
2025-10-26 22:21:17 -04:00
committed by GitHub
parent e87fb82f0e
commit 477cc076d8
26 changed files with 469 additions and 79 deletions
+4 -1
View File
@@ -17,7 +17,10 @@
//Status updates, death etc.
update_icons()
/mob/living/carbon/alien/handle_mutations_and_radiation()
/mob/living/carbon/alien/handle_radiation()
. = ..()
if(.)
return
// Currently both Dionaea and larvae like to eat radiation, so I'm defining the
// rad absorbtion here. This will need to be changed if other baby aliens are added.
+4 -1
View File
@@ -1,7 +1,10 @@
/mob/living/carbon/brain/handle_breathing()
return
/mob/living/carbon/brain/handle_mutations_and_radiation()
/mob/living/carbon/brain/handle_radiation()
. = ..()
if(.)
return
if (radiation)
if (radiation > 100)
radiation = 100
+37 -51
View File
@@ -206,6 +206,37 @@
to_chat(src, span_danger("Your legs won't respond properly, you fall down!"))
Weaken(10)
/mob/living/carbon/human/handle_mutations()
. = ..()
if(.)
return
if(inStasisNow())
return
if(getFireLoss())
if((COLD_RESISTANCE in mutations) || (prob(1)))
heal_organ_damage(0,1)
if(getBruteLoss()) //Fireloss gets this RNG change so may as well give bruteloss it as well.
if(prob(1))
heal_organ_damage(1,0)
if((mRegen in mutations))
var/heal = rand(0.2,1.3)
if(prob(50))
for(var/obj/item/organ/external/O in organs) //HAS to be organs and NOT bad_external_organs as a fully healed limb w/ internal damage will NOT be in bad_external_organs
for(var/datum/wound/W in O.wounds)
if(W.bleeding())
W.damage = max(W.damage - heal, 0)
if(W.damage <= 0)
O.wounds -= W
if(W.internal)
W.damage = max(W.damage - heal, 0)
if(W.damage <= 0)
O.wounds -= W
else
heal_organ_damage(heal,heal)
// 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.
@@ -227,65 +258,20 @@
// Additionally, RADIATION_SPEED_COEFFICIENT = 0.1
/mob/living/carbon/human/handle_mutations_and_radiation() //Radiation rework! Now with 'accumulated_rads'
/mob/living/carbon/human/handle_radiation() //Radiation rework! Now with 'accumulated_rads'
. = ..()
if(.)
return
if(inStasisNow())
return
if(getFireLoss())
if((COLD_RESISTANCE in mutations) || (prob(1)))
heal_organ_damage(0,1)
if(stat != DEAD)
if((mRegen in mutations))
var/heal = rand(0.2,1.3)
if(prob(50))
for(var/obj/item/organ/external/O in bad_external_organs)
for(var/datum/wound/W in O.wounds)
if(W.bleeding())
W.damage = max(W.damage - heal, 0)
if(W.damage <= 0)
O.wounds -= W
if(W.internal)
W.damage = max(W.damage - heal, 0)
if(W.damage <= 0)
O.wounds -= W
else
heal_organ_damage(heal,heal)
radiation = CLAMP(radiation,0,5000) //Max of 100Gy. If you reach that...You're going to wish you were dead. You probably will be dead.
accumulated_rads = CLAMP(accumulated_rads,0,5000) //Max of 100Gy as well. You should never get higher than this. You will be dead before you can reach this.
radiation = CLAMP(radiation,0,RADIATION_CAP) //Max of 100Gy. If you reach that...You're going to wish you were dead. You probably will be dead.
accumulated_rads = CLAMP(accumulated_rads,0,RADIATION_CAP) //Max of 100Gy 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)
glow_override = FALSE
set_light(0)
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)
glow_override = TRUE
set_light(max(1,min(5,radiation/15)), max(1,min(10,radiation/25)), species.get_flesh_colour(src))
// END DOGSHIT SNOWFLAKE
var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs
if(rad_organ && !rad_organ.is_broken())
var/rads = radiation/25
radiation -= (rads * species.rad_removal_mod)
adjust_nutrition(rads * species.rad_removal_mod)
adjustBruteLoss(-(rads * species.rad_removal_mod))
adjustFireLoss(-(rads * species.rad_removal_mod))
adjustOxyLoss(-(rads * species.rad_removal_mod))
adjustToxLoss(-(rads * species.rad_removal_mod))
updatehealth()
return
var/obj/item/organ/internal/brain/slime/core = locate() in internal_organs
if(core)
return
var/obj/item/organ/internal/brain/shadekin/s_brain = locate() in internal_organs
if(s_brain)
return
if(reagents.has_reagent(REAGENT_ID_PRUSSIANBLUE)) //Prussian Blue temporarily stops radiation effects.
return
@@ -26,7 +26,7 @@
assisted_langs = list()
species_component = /datum/component/burninlight/shadow // Until a parent component like xenochimera have is needed, only handles burning in light.
species_component = list(/datum/component/burninlight/shadow) // Until a parent component like xenochimera have is needed, only handles burning in light.
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
spawn(1)
@@ -100,7 +100,7 @@
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
species_component = /datum/component/shadekin
species_component = list(/datum/component/shadekin, /datum/component/radiation_effects/shadekin)
component_requires_late_recalc = TRUE
/datum/species/shadekin/handle_death(var/mob/living/carbon/human/H)
@@ -246,7 +246,7 @@
var/list/env_traits = list()
var/pixel_offset_x = 0 // Used for offsetting 64x64 and up icons.
var/pixel_offset_y = 0 // Used for offsetting 64x64 and up icons.
var/rad_levels = NORMAL_RADIATION_RESISTANCE //For handle_mutations_and_radiation
var/rad_levels = NORMAL_RADIATION_RESISTANCE //For handle_radiation
var/rad_removal_mod = 1
var/ambulant_blood = FALSE // Force changeling blood effects
@@ -359,7 +359,7 @@
var/list/food_preference = list() //RS edit
var/food_preference_bonus = 0
var/datum/component/species_component = null // The component that this species uses. Example: Xenochimera use /datum/component/xenochimera
var/list/species_component = list() // The component that this species uses. Example: Xenochimera use /datum/component/xenochimera
var/component_requires_late_recalc = FALSE // If TRUE, the component will do special recalculation stuff at the end of update_icons_body()
// For Lleill and Hanner
@@ -804,8 +804,9 @@
..()
/datum/species/proc/apply_components(var/mob/living/carbon/human/H)
if(species_component)
H.LoadComponent(species_component)
if(LAZYLEN(species_component))
for(var/component in species_component)
H.LoadComponent(component)
/datum/species/proc/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base, var/reset_dna = TRUE) // Traitgenes reset_dna flag required, or genes get reset on resleeve
ASSERT(src)
@@ -35,6 +35,8 @@ var/datum/species/shapeshifter/promethean/prometheans
secondary_langs = list(LANGUAGE_PROMETHEAN, LANGUAGE_SOL_COMMON) // For some reason, having this as their species language does not allow it to be chosen.
assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) // Prometheans are weird, let's just assume they can use basically any language.
species_component = list(/datum/component/radiation_effects/promethean)
blood_name = "gelatinous ooze"
blood_reagents = REAGENT_ID_SLIMEJELLY
@@ -657,13 +657,14 @@
return 1
return 0
/mob/living/simple_mob/protean_blob/handle_mutations_and_radiation()
/mob/living/simple_mob/protean_blob/handle_radiation()
..()
if(!humanform)
to_chat(src, span_giant(span_boldwarning("You are currently a blob without a humanform and should be deleted shortly Please report what you were doing when this error occurred to the admins.")))
stack_trace("URGENT, SERVER-CRASHING ISSUE: A protean blob does not have a humanform! src = [src] ckey = [ckey]! The blob has been deleted.")
qdel(src)
return
humanform.handle_mutations_and_radiation()
humanform.handle_radiation()
/mob/living/simple_mob/protean_blob/update_icon()
..()
@@ -490,7 +490,7 @@
reagent_tag = IS_ZADDAT
species_component = /datum/component/burninlight // Until a parent component like xenochimera have is needed, only handles burning in light.
species_component = list(/datum/component/burninlight) // Until a parent component like xenochimera have is needed, only handles burning in light.
heat_discomfort_strings = list(
"Your joints itch.",
@@ -564,6 +564,8 @@
min_age = 18
max_age = 300
species_component = list(/datum/component/radiation_effects/diona)
economic_modifier = 10
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
@@ -1548,7 +1550,7 @@
tail = "tail" //Spider tail.
icobase_tail = 1
species_component = /datum/component/weaver
species_component = list(/datum/component/weaver)
inherent_verbs = list(
/mob/living/carbon/human/proc/tie_hair)
@@ -1741,7 +1743,7 @@
reagent_tag = IS_CHIMERA
species_component = /datum/component/xenochimera
species_component = list(/datum/component/xenochimera)
/datum/species/xenochimera/handle_environment_special(var/mob/living/carbon/human/H)
//Cold/pressure effects when not regenerating
@@ -677,3 +677,9 @@
else if(istype(ex_organ, /obj/item/organ/external/chest))
ex_organ.encased = FALSE
/datum/trait/negative/rad_weakness
name = "Radiation Weakness"
desc = "You are approximately 50% more susceptible to radiation, and it dissipates slower from your body."
cost = -2
var_changes = list("radiation_mod" = 1.5, "rad_removal_mod" = 0.5, "rad_levels" = WEAKENED_RADIATION_RESISTANCE)
@@ -1795,3 +1795,17 @@
/datum/trait/neutral/strongimmunesystem/apply(datum/species/S, mob/living/carbon/human/H, trait_prefs)
..()
ADD_TRAIT(H, STRONG_IMMUNITY_TRAIT, ROUNDSTART_TRAIT)
/datum/trait/neutral/glowing_radiation
name = "Radioactive Glow"
desc = "You emit a glow when exposed to radiation! This does not prevent you from being harmed by radiation."
cost = 0
has_preferences = list("glow_color" = list(TRAIT_PREF_TYPE_COLOR, "Glow color", TRAIT_VAREDIT_TARGET_MOB, "#c3f314"))
added_component_path = /datum/component/radiation_effects
excludes = list(/datum/trait/positive/radioactive_heal)
/datum/trait/neutral/glowing_radiation/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs)
..()
var/datum/component/radiation_effects/G = H.GetComponent(added_component_path)
if(trait_prefs)
G.radiation_color = trait_prefs["glow_color"]
@@ -542,3 +542,23 @@
can_take = ORGANICS
var_changes = list("virus_immune" = TRUE)
/datum/trait/positive/radioactive_heal
name = "Radioactive Heal"
desc = "You heal when exposed to radiation instead of becoming ill. You can also choose to emit a glow when irradiated."
cost = 6
is_genetrait = TRUE
hidden = FALSE
has_preferences = list("glow_color" = list(TRAIT_PREF_TYPE_COLOR, "Glow color", TRAIT_VAREDIT_TARGET_MOB, "#c3f314",),
"glow_enabled" = list(TRAIT_PREF_TYPE_BOOLEAN, "Glow enabled on spawn", TRAIT_VAREDIT_TARGET_MOB, FALSE))
added_component_path = /datum/component/radiation_effects
excludes = list(/datum/trait/neutral/glowing_radiation, /datum/trait/positive/rad_resistance, /datum/trait/positive/rad_resistance_extreme, /datum/trait/positive/rad_immune, /datum/trait/negative/rad_weakness)
/datum/trait/positive/radioactive_heal/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs)
..()
var/datum/component/radiation_effects/G = H.GetComponent(added_component_path)
if(trait_prefs)
G.radiation_color = trait_prefs["glow_color"]
G.glows = trait_prefs["glow_enabled"]
G.radiation_healing = TRUE
+2 -5
View File
@@ -159,13 +159,10 @@
if(AGONY)
halloss += max((effect * blocked), 0) // Useful for objects that cause "subdual" damage. PAIN!
if(IRRADIATE)
/*
var/rad_protection = check_protection ? getarmor(null, "rad")/100 : 0
radiation += max((1-rad_protection)*effect/(blocked+1),0)//Rads auto check armor
*/
var/rad_protection = getarmor(null, "rad")
rad_protection = (100-rad_protection)/100
radiation += max((effect * rad_protection), 0)
if(!(SEND_SIGNAL(src, COMSIG_LIVING_IRRADIATE_EFFECT, effect, effecttype, blocked, check_protection, rad_protection) & COMPONENT_BLOCK_IRRADIATION))
radiation += max((effect * rad_protection), 0)
if(STUTTER)
if(status_flags & CANSTUN) // stun is usually associated with stutter
stuttering = max(stuttering,(effect * blocked))
+11 -3
View File
@@ -25,7 +25,8 @@
handle_breathing()
//Mutations and radiation
handle_mutations_and_radiation()
handle_mutations()
handle_radiation()
@@ -89,8 +90,15 @@
/mob/living/proc/handle_breathing()
return
/mob/living/proc/handle_mutations_and_radiation()
return
/mob/living/proc/handle_mutations()
SHOULD_CALL_PARENT(TRUE)
if(SEND_SIGNAL(src, COMSIG_HANDLE_MUTATIONS) & COMPONENT_BLOCK_LIVING_MUTATIONS)
return COMPONENT_BLOCK_LIVING_MUTATIONS
/mob/living/proc/handle_radiation()
SHOULD_CALL_PARENT(TRUE)
if(SEND_SIGNAL(src, COMSIG_HANDLE_RADIATION) & COMPONENT_BLOCK_LIVING_RADIATION)
return COMPONENT_BLOCK_LIVING_RADIATION
/mob/living/proc/handle_chemicals_in_body()
return
+2
View File
@@ -22,6 +22,8 @@
qdel(src) // Decayed to nothing
else
rad_power = new_power
if(rad_power > 1e15) // Arbitrary cap to prevent going to infinity
rad_power = 1e15
if(!flat)
range = min(round(sqrt(rad_power / CONFIG_GET(number/radiation_lower_limit))), 31) // R = rad_power / dist**2 - Solve for dist
return