Radiation Refactor (#19270)

* Part 1

* WIP

* The rest of these

* More stuff

* Whoops, did that wrong

* typo

* gweeen

* This all works

* SHOWER

* Rads

* awa

* rad

* Update life.dm

* edits

* Makes lvl 3 rads give you a warning.

You should already know by this point, but this makes it EXTRA clear you're getting fucked

* Update vorestation.dme

* aaa

* propagate

* gwah

* more fixes

* AAA

* Update radiation.dm

* Update radiation.dm

* mobs rads

* rads

* fix this

* Update _reagents.dm

* these

* Get rid of these

* rad

* Update config.txt

* fixed

* Update radiation_effects.dm
This commit is contained in:
Cameron Lennox
2026-03-22 12:29:09 -04:00
committed by GitHub
parent d91baf9c9f
commit cbc4151bfb
113 changed files with 2044 additions and 551 deletions
@@ -21,7 +21,20 @@
attack_verb = "splashes"
/datum/blob_type/radioactive_ooze/on_pulse(var/obj/structure/blob/B)
SSradiation.radiate(B, 200)
radiation_pulse(
src,
max_range = 5,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
strength = 75
)
/datum/blob_type/radioactive_ooze/on_chunk_tick(obj/item/blobcore_chunk/B)
SSradiation.radiate(B, rand(25,100))
radiation_pulse(
src,
max_range = 3,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE * 0.5,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = 25
)
@@ -34,17 +34,26 @@
var/obj/item/clothing/head/helmet/space/rig/helmet = holder.helmet
var/obj/item/clothing/gloves/gauntlets/rig/gloves = holder.gloves
var/list/items_to_update = list()
to_chat(H, span_boldnotice("You activate your suit's powered radiation shielding."))
stored_rad_armor = holder.armor["rad"]
if(boots)
boots.armor["rad"] = 100
items_to_update += boots
if(chest)
chest.armor["rad"] = 100
items_to_update += chest
if(helmet)
helmet.armor["rad"] = 100
items_to_update += helmet
if(gloves)
gloves.armor["rad"] = 100
items_to_update += gloves
holder.armor["rad"] = 100
items_to_update += holder
for(var/obj/item/part in items_to_update)
ADD_TRAIT(part, TRAIT_RADIATION_PROTECTED_CLOTHING, MOD_TRAIT)
/obj/item/rig_module/rad_shield/deactivate()
@@ -57,20 +66,30 @@
var/obj/item/clothing/head/helmet/space/rig/helmet = holder.helmet
var/obj/item/clothing/gloves/gauntlets/rig/gloves = holder.gloves
var/list/items_to_update = list()
to_chat(H, span_danger("You deactivate your suit's powered radiation shielding."))
if(boots)
boots.armor["rad"] = stored_rad_armor
items_to_update += boots
if(chest)
chest.armor["rad"] = stored_rad_armor
items_to_update += chest
if(helmet)
helmet.armor["rad"] = stored_rad_armor
items_to_update += helmet
if(gloves)
gloves.armor["rad"] = stored_rad_armor
items_to_update += gloves
holder.armor["rad"] = stored_rad_armor
items_to_update += holder
stored_rad_armor = 0
for(var/obj/item/part in items_to_update)
REMOVE_TRAIT(part, TRAIT_RADIATION_PROTECTED_CLOTHING, MOD_TRAIT)
/obj/item/rig_module/rad_shield/advanced
name = "advanced radiation absorption device"
desc = "The acronym of this device - R.A.D. - and its full name both convey the application of the module. It has a changelog inscribed \
+9
View File
@@ -88,6 +88,11 @@
body_parts_covered = HEAD|FACE|EYES
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100)
/obj/item/clothing/head/radiation/Initialize(mapload)
. = ..()
AddElement(/datum/element/radiation_protected_clothing)
/obj/item/clothing/suit/radiation
name = "Radiation suit"
desc = "A suit that protects against radiation. Label: Made with lead, do not eat insulation."
@@ -102,6 +107,10 @@
flags_inv = HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER
item_flags = THICKMATERIAL
/obj/item/clothing/suit/radiation/Initialize(mapload)
. = ..()
AddElement(/datum/element/radiation_protected_clothing)
/obj/item/clothing/suit/radiation/teshari
name = "Small radiation suit"
desc = "A specialist suit that protects against radiation, designed specifically for use by Teshari. Made to order by Aether."
+32
View File
@@ -96,6 +96,38 @@
desc = "A " + MAT_URANIUM + " coin. You probably don't want to store this in your pants pocket..."
icon_state = "coin_uranium"
matter = list(MAT_URANIUM = 250)
var/last_event = 0
var/active = 0
/obj/item/coin/uranium/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/coin/uranium/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/coin/uranium/process()
radiate()
..()
/obj/item/coin/uranium/proc/radiate()
SIGNAL_HANDLER
if(active)
return
if(world.time <= last_event + 1.5 SECONDS)
return
active = TRUE
radiation_pulse(
src,
max_range = 1,
threshold = RAD_LIGHT_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = 2
)
last_event = world.time
active = FALSE
/obj/item/coin/platinum
name = MAT_PLATINUM + " coin"
+13 -1
View File
@@ -29,9 +29,21 @@
else if(activeFor == leaveBelt)
GLOB.command_announcement.Announce("The [using_map.facility_type] has passed the radiation belt. Please allow for up to one minute while radiation levels dissipate, and report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert")
/datum/event/radiation_storm/proc/radiate()
//This sucks. Just mutate.
/*
var/radiation_level = rand(15, 35)
for(var/z in using_map.station_levels)
SSradiation.z_radiate(locate(1, 1, z), radiation_level, 1)
var/turf/epicentre = locate(round(world.maxx / 2), round(world.maxy / 2), z)
if(epicentre)
radiation_pulse(
epicentre,
max_range = 5,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
)
*/
for(var/mob/living/carbon/C in GLOB.living_mob_list)
if(!(C.z in using_map.station_levels) || C.isSynthetic() || isbelly(C.loc))
+7 -1
View File
@@ -37,7 +37,13 @@
continue
//Todo: Apply some burn damage from the heat of the sun. Until then, enjoy some moderate radiation.
L.rad_act(rand(15, 30))
radiation_pulse(
L,
max_range = 1,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
strength = rand(10, 50)
)
/datum/event/solar_storm/end()
GLOB.command_announcement.Announce("The solar storm has passed the [using_map.facility_type]. It is now safe to resume EVA activities. Please report to medbay if you experience any unusual symptoms. ", "Anomaly Alert")
@@ -29,9 +29,41 @@
radiate()
/datum/event2/event/radiation_storm/proc/radiate()
//This sucks. Just mutate.
/*
var/radiation_level = rand(15, 35)
for(var/z in using_map.station_levels)
SSradiation.z_radiate(locate(1, 1, z), radiation_level, 1)
var/turf/epicentre = locate(round(world.maxx / 2), round(world.maxy / 2), z)
if(epicentre)
radiation_pulse(
epicentre,
max_range = 5,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
)
*/
for(var/mob/living/carbon/C in GLOB.living_mob_list)
if(!(C.z in using_map.station_levels) || C.isSynthetic() || isbelly(C.loc))
continue
var/area/A = get_area(C)
if(!A)
continue
if(A.flag_check(RAD_SHIELDED))
continue
if(ishuman(C))
var/mob/living/carbon/human/H = C
var/chance = 5.0
chance -= (chance / 100) * C.getarmor(null, "rad")
if(prob(chance))
if (prob(75))
randmutb(H) // Applies bad mutation
domutcheck(H,null,MUTCHK_FORCED)
else
randmutg(H) // Applies good mutation
domutcheck(H,null,MUTCHK_FORCED)
H.UpdateAppearance()
/datum/event2/event/radiation_storm/end()
GLOB.command_announcement.Announce("The station has passed the radiation belt. \
@@ -49,4 +49,10 @@
continue
//Todo: Apply some burn damage from the heat of the sun. Until then, enjoy some moderate radiation.
L.rad_act(rand(15, 30))
radiation_pulse(
L,
max_range = 1,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
strength = rand(10, 50)
)
+42 -3
View File
@@ -5,6 +5,40 @@
item_state = "diamond"
default_type = MAT_SUPERMATTER
apply_colour = TRUE
var/last_event = 0
/// Mutex to prevent infinite recursion when propagating radiation pulses
var/active = null
/obj/item/stack/material/supermatter/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/stack/material/supermatter/process()
radiate()
..()
/obj/item/stack/material/supermatter/proc/radiate()
SIGNAL_HANDLER
if(active)
return
if(world.time <= last_event + 1.5 SECONDS)
return
active = TRUE
radiation_pulse(
src,
max_range = (amount * 0.2), //10 range at 50 amount
threshold = RAD_HEAVY_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
minimum_exposure_time = NEBULA_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = amount * 0.5 //2 sheets = 1 rad, 50 sheets = 25 rads.
)
last_event = world.time
active = FALSE
/obj/item/stack/material/supermatter/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/stack/material/supermatter/proc/update_mass() // Due to how dangerous they can be, the item will get heavier and larger the more are in the stack.
slowdown = amount / 10
@@ -20,7 +54,6 @@
. = ..()
update_mass()
SSradiation.radiate(src, 5 + amount)
var/mob/living/M = user
if(!istype(M))
return
@@ -47,9 +80,15 @@
/obj/item/stack/material/supermatter/ex_act(severity) // An incredibly hard to manufacture material, SM chunks are unstable by their 'stabilized' nature.
if(prob((4 / severity) * 20))
SSradiation.radiate(get_turf(src), amount * 4)
radiation_pulse(
src,
max_range = amount,
threshold = RAD_HEAVY_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE * 5,
minimum_exposure_time = 0,
strength = amount * 10
)
explosion(get_turf(src),round(amount / 12) , round(amount / 6), round(amount / 3), round(amount / 25))
qdel(src)
return
SSradiation.radiate(get_turf(src), amount * 2)
..()
+2 -2
View File
@@ -641,7 +641,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
gas_analyzing += "Temperature: [round(environment.temperature-T0C,0.1)]&deg;C ([round(environment.temperature,0.1)]K)"
gas_analyzing += "Heat Capacity: [round(environment.heat_capacity(),0.1)]"
to_chat(src, span_notice("[jointext(gas_analyzing, "<br>")]"))
/*
/mob/observer/dead/verb/check_radiation()
set name = "Check Radiation"
set category = "Ghost.Game"
@@ -650,7 +650,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(t)
var/rads = SSradiation.get_rads_at_turf(t)
to_chat(src, span_notice("Radiation level: [rads ? rads : "0"] Bq."))
*/
/mob/observer/dead/verb/view_manfiest()
set name = "Show Crew Manifest"
set category = "Ghost.Game"
+4 -2
View File
@@ -6,13 +6,13 @@
if(.)
return
if (radiation)
if (radiation > 100)
throw_alert("irradiated", /atom/movable/screen/alert/irradiated)
if(radiation > 100)
radiation = 100
if(!container)//If it's not in an MMI
to_chat(src, span_red("You feel weak."))
else//Fluff-wise, since the brain can't detect anything itself, the MMI handles thing like that
to_chat(src, span_red("STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED."))
switch(radiation)
if(1 to 49)
radiation--
@@ -35,6 +35,8 @@
radiation -= 3
adjustToxLoss(3)
updatehealth()
else
clear_alert("irradiated")
/mob/living/carbon/brain/handle_environment(datum/gas_mixture/environment)
@@ -251,7 +251,7 @@
/mob/living/carbon/human/inStasisNow()
var/stasisValue = getStasis()
if(stasisValue && (life_tick % stasisValue))
if(stasisValue && (life_tick % stasisValue) || HAS_TRAIT(src, TRAIT_STASIS))
return 1
return 0
@@ -610,3 +610,11 @@ emp_act
return TRUE
return FALSE
///Get all the clothing on a specific body part
/mob/living/carbon/human/proc/get_clothing_on_part(obj/item/organ/external/def_zone)
var/list/covering_part = list()
for(var/obj/item/clothing/equipped in get_equipped_items(INCLUDE_ABSTRACT))
if(equipped.body_parts_covered & def_zone.body_part)
covering_part += equipped
return covering_part
+24 -21
View File
@@ -47,37 +47,38 @@
voice = GetVoice()
var/stasis = inStasisNow()
var/stasis = (inStasisNow())
if(getStasis() > 2)
Sleeping(20)
//No need to update all of these procs if the guy is dead.
fall() //Prevents people from floating
if(stat != DEAD && !stasis)
//Updates the number of stored chemicals for powers
handle_changeling()
if(!stasis)
if(stat != DEAD)
//Updates the number of stored chemicals for powers
handle_changeling()
//Organs and blood
handle_organs()
stabilize_body_temperature() //Body temperature adjusts itself (self-regulation)
weightgain()
handle_shock()
//Organs and blood
handle_organs()
stabilize_body_temperature() //Body temperature adjusts itself (self-regulation)
weightgain()
handle_shock()
handle_pain()
handle_pain()
SEND_SIGNAL(src,COMSIG_HANDLE_ALLERGENS, chem_effects[CE_ALLERGEN])
SEND_SIGNAL(src,COMSIG_HANDLE_ALLERGENS, chem_effects[CE_ALLERGEN])
handle_medical_side_effects()
handle_medical_side_effects()
handle_heartbeat()
handle_nif()
if(phobias)
handle_phobias()
if(!client)
species.handle_npc(src)
handle_heartbeat()
handle_nif()
if(phobias)
handle_phobias()
if(!client)
species.handle_npc(src)
else if(stat == DEAD && !stasis)
handle_defib_timer()
else if(stat == DEAD)
handle_defib_timer()
//Handle any species related components we may have. Ex: Shadekin, Xenochimera, etc. Not STAT checked because those do statchecks in their own code.
handle_species_components()
@@ -262,11 +263,12 @@
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)
clear_alert("irradiated")
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(reagents.has_reagent(REAGENT_ID_PRUSSIANBLUE)) //Prussian Blue temporarily stops radiation effects.
if(HAS_TRAIT(src, TRAIT_HALT_RADIATION_EFFECTS)) //If we have a trait that halts radiation effects, then we just stop here. No need to do any of the checks below.
return
var/damage = 0
@@ -334,6 +336,7 @@
else if (radiation >= GLOB.radiation_levels[species.rad_levels]["danger_3"] && radiation < GLOB.radiation_levels[species.rad_levels]["danger_4"]) //Equivalent of 8.0 to 30 Gy.
throw_alert("irradiated", /atom/movable/screen/alert/irradiated)
damage = 10
radiation -= 100 * RADIATION_SPEED_COEFFICIENT * species.rad_removal_mod
accumulated_rads += 100 * RADIATION_SPEED_COEFFICIENT
@@ -206,13 +206,6 @@
else
return ..()
/mob/living/simple_mob/slime/promethean/rad_act(severity)
rad_glow += severity
rad_glow = CLAMP(rad_glow,0,250)
if(rad_glow > 1)
set_light(max(1,min(5,rad_glow/15)), max(1,min(10,rad_glow/25)), color)
update_icon()
/mob/living/simple_mob/slime/promethean/bullet_act(obj/item/projectile/P)
if(humanform)
return humanform.bullet_act(P)
@@ -307,14 +307,6 @@
else
return ..()
/mob/living/simple_mob/protean_blob/rad_act(severity)
if(istype(loc, /obj/item/rig))
return //Don't irradiate us while we're in rig mode
if(humanform)
return humanform.rad_act(severity)
else
return ..()
/mob/living/simple_mob/protean_blob/bullet_act(obj/item/projectile/P)
if(humanform)
return humanform.bullet_act(P)
@@ -442,6 +442,14 @@
hidden = FALSE
activation_message="Your body feels mundane."
/datum/trait/positive/rad_immune/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..()
ADD_TRAIT(H, TRAIT_RADIMMUNE, ROUNDSTART_TRAIT)
/datum/trait/positive/rad_immune/unapply(var/datum/species/S,var/mob/living/carbon/human/H)
..()
REMOVE_TRAIT(H, TRAIT_RADIMMUNE, ROUNDSTART_TRAIT)
/datum/trait/positive/vibration_sense
name = "Vibration Sense"
desc = "Allows you to sense subtle vibrations nearby, even if the source cannot be seen."
-1
View File
@@ -32,7 +32,6 @@
return name
/mob/living/Destroy()
SSradiation.listeners -= src
remove_all_modifiers(TRUE)
QDEL_NULL(say_list)
@@ -522,8 +522,14 @@
..()
/mob/living/simple_mob/slime/xenobio/green/proc/irradiate()
SSradiation.radiate(src, rads)
radiation_pulse(
src,
max_range = 5,
threshold = RAD_LIGHT_INSULATION,
chance = rads * 0.5,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = rads
)
/mob/living/simple_mob/slime/xenobio/pink
+15 -2
View File
@@ -578,7 +578,13 @@ GLOBAL_DATUM(planet_virgo3b, /datum/planet/virgo3b)
if(!T.is_outdoors())
return // They're indoors, so no need to irradiate them with fallout.
L.rad_act(rand(direct_rad_low, direct_rad_high))
radiation_pulse(
L,
max_range = 1,
threshold = RAD_VERY_LIGHT_INSULATION,
chance = rand(fallout_rad_low, fallout_rad_high),
strength = rand(fallout_rad_low, fallout_rad_high)
)
// This makes random tiles near people radioactive for awhile.
// Tiles far away from people are left alone, for performance.
@@ -590,7 +596,14 @@ GLOBAL_DATUM(planet_virgo3b, /datum/planet/virgo3b)
if(!istype(T))
return
if(T.is_outdoors())
SSradiation.radiate(T, rand(fallout_rad_low, fallout_rad_high))
radiation_pulse(
T,
max_range = 7,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = rand(fallout_rad_low, fallout_rad_high)
)
/datum/weather/virgo3b/fallout/temp
name = "short-term fallout"
+16 -2
View File
@@ -582,7 +582,14 @@ GLOBAL_DATUM(planet_virgo3c, /datum/planet/virgo3c)
if(!T.is_outdoors())
return // They're indoors, so no need to irradiate them with fallout.
L.rad_act(rand(direct_rad_low, direct_rad_high))
radiation_pulse(
L,
max_range = 1,
threshold = RAD_MEDIUM_INSULATION,
chance = rand(direct_rad_low, direct_rad_high),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = rand(direct_rad_low, direct_rad_high)
)
// This makes random tiles near people radioactive for awhile.
// Tiles far away from people are left alone, for performance.
@@ -594,7 +601,14 @@ GLOBAL_DATUM(planet_virgo3c, /datum/planet/virgo3c)
if(!istype(T))
return
if(T.is_outdoors())
SSradiation.radiate(T, rand(fallout_rad_low, fallout_rad_high))
radiation_pulse(
T,
max_range = 1,
threshold = RAD_MEDIUM_INSULATION,
chance = rand(direct_rad_low, direct_rad_high),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = rand(fallout_rad_low, fallout_rad_high)
)
/datum/weather/virgo3c/fallout/temp
name = "short-term fallout"
+17 -2
View File
@@ -553,7 +553,15 @@ GLOBAL_DATUM(planet_virgo4, /datum/planet/virgo4)
if(!T.is_outdoors())
return // They're indoors, so no need to irradiate them with fallout.
L.rad_act(rand(direct_rad_low, direct_rad_high))
radiation_pulse(
L,
max_range = 1,
threshold = RAD_MEDIUM_INSULATION,
chance = rand(direct_rad_low, direct_rad_high),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = rand(direct_rad_low, direct_rad_high)
)
// This makes random tiles near people radioactive for awhile.
// Tiles far away from people are left alone, for performance.
@@ -565,7 +573,14 @@ GLOBAL_DATUM(planet_virgo4, /datum/planet/virgo4)
if(!istype(T))
return
if(T.is_outdoors())
SSradiation.radiate(T, rand(fallout_rad_low, fallout_rad_high))
radiation_pulse(
T,
max_range = 5,
threshold = RAD_MEDIUM_INSULATION,
chance = rand(direct_rad_low, direct_rad_high),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = rand(fallout_rad_low, fallout_rad_high)
)
/datum/weather/virgo4/fallout/temp
name = "short-term fallout"
+14 -2
View File
@@ -333,7 +333,13 @@
radiation += plasma_temperature/2
plasma_temperature = 0
SSradiation.radiate(src, radiation)
radiation_pulse(
src,
max_range = 7,
threshold = RAD_HEAVY_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
strength = energy * 0.001 //Might need to be increased.
)
Radiate()
/obj/effect/fusion_em_field/proc/Radiate()
@@ -539,7 +545,13 @@
//Reaction radiation is fairly buggy and there's at least three procs dealing with radiation here, this is to ensure constant radiation output.
/obj/effect/fusion_em_field/proc/radiation_scale()
SSradiation.radiate(src, 2 + plasma_temperature / PLASMA_TEMP_RADIATION_DIVISIOR)
radiation_pulse(
src,
max_range = 5,
threshold = RAD_MEDIUM_INSULATION,
chance = (URANIUM_IRRADIATION_CHANCE + (plasma_temperature / PLASMA_TEMP_RADIATION_DIVISIOR)),
strength = energy * 0.01 //Might need to be increased.
)
//Somehow fixing the radiation issue managed to break this, but moving it to it's own proc seemed to have fixed it. I don't know.
/obj/effect/fusion_em_field/proc/temp_dump()
@@ -11,6 +11,34 @@
var/fuel_colour
var/radioactivity = 0
var/const/initial_amount = 3000000
var/last_event = 0
/// Mutex to prevent infinite recursion when propagating radiation pulses
var/active = null
/obj/item/fuel_assembly/process()
radiate()
/obj/item/fuel_assembly/proc/radiate()
SIGNAL_HANDLER
if(active)
return
if(world.time <= last_event + 1.5 SECONDS)
return
active = TRUE
radiation_pulse(
src,
max_range = (radioactivity * 0.5),
threshold = RAD_HEAVY_INSULATION,
chance = DEFAULT_RADIATION_CHANCE,
strength = radioactivity * 0.5
)
last_event = world.time
active = FALSE
/obj/item/fuel_assembly/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/fuel_assembly/Initialize(mapload, var/_material, var/_colour)
. = ..()
@@ -38,17 +66,6 @@
add_overlay(list(I, image(icon, "fuel_assembly_bracket")))
rod_quantities[fuel_type] = initial_amount
/obj/item/fuel_assembly/process()
if(!radioactivity)
return PROCESS_KILL
if(istype(loc, /turf))
SSradiation.radiate(src, max(1,CEILING(radioactivity/30, 1)))
/obj/item/fuel_assembly/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
// Mapper shorthand.
/obj/item/fuel_assembly/deuterium/Initialize(mapload)
. = ..(mapload, MAT_DEUTERIUM)
@@ -116,11 +116,13 @@ GLOBAL_LIST(fusion_reactions)
var/turf/origin = get_turf(holder)
holder.Rupture()
qdel(holder)
var/radiation_level = 200
// Copied from the SM for proof of concept. //Not any more --Cirra //Use the whole z proc --Leshana
SSradiation.z_radiate(locate(1, 1, holder.z), radiation_level, 1)
radiation_pulse(
holder,
max_range = 50,
threshold = RAD_HEAVY_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
strength = 500
)
for(var/mob/living/mob in GLOB.living_mob_list)
var/turf/T = get_turf(mob)
@@ -135,8 +137,7 @@ GLOBAL_LIST(fusion_reactions)
spawn(5)
if(I && I.loc)
qdel(I)
sleep(5)
qdel(holder)
explosion(origin, 1, 2, 5)
return 1
+8 -1
View File
@@ -378,7 +378,14 @@ GLOBAL_LIST_EMPTY(gravity_generators)
/obj/machinery/gravity_generator/main/proc/pulse_radiation()
SSradiation.radiate(src, 200)
radiation_pulse(
src,
max_range = 7,
threshold = RAD_HEAVY_INSULATION,
chance = DEFAULT_RADIATION_CHANCE * 2,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = charge_count * 2
)
/obj/machinery/gravity_generator/main/proc/update_gravity(var/on)
for(var/area/A in src.areas)
+14 -2
View File
@@ -385,13 +385,25 @@
/obj/machinery/power/port_gen/pacman/super/UseFuel()
//produces a tiny amount of radiation when in use
if (prob(2*power_output))
SSradiation.radiate(src, 4)
radiation_pulse(
src,
max_range = 2,
threshold = RAD_HEAVY_INSULATION,
chance = DEFAULT_RADIATION_CHANCE,
strength = power_gen * 0.01
)
..()
/obj/machinery/power/port_gen/pacman/super/explode()
//a nice burst of radiation
var/rads = 50 + (sheets + sheet_left)*1.5
SSradiation.radiate(src, (max(20, rads)))
radiation_pulse(
src,
max_range = (rads/10),
threshold = RAD_HEAVY_INSULATION,
chance = DEFAULT_RADIATION_CHANCE,
strength = rads
)
explosion(src.loc, 3, 3, 5, 3)
qdel(src)
+15 -2
View File
@@ -144,7 +144,14 @@
..()
add_avail(power_gen)
if(panel_open && irradiate)
SSradiation.radiate(src, 60)
radiation_pulse(
src,
max_range = 3,
threshold = RAD_MEDIUM_INSULATION,
chance = DEFAULT_RADIATION_CHANCE,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = power_gen * 0.01 //1000 power = 10 rads. 10000 power = 100 rads. You can get creative with rad collectors if you want.
)
/obj/machinery/power/rtg/RefreshParts()
var/part_level = 0
@@ -593,9 +600,15 @@
var/turf/T = get_turf(src)
qdel(src)
if(T)
radiation_pulse(
T,
max_range = 50,
threshold = RAD_HEAVY_INSULATION,
chance = DEFAULT_RADIATION_CHANCE * 3,
strength = power_gen * 0.01 ///1MW = 1000 rads. If you blow up a BLACK HOLE ENGINE, you deserve the radiation that comes with it.
)
empulse(T, 12, 14, 16, 18)
explosion(T, 7, 12, 18, 20)
SSradiation.radiate(T, 200)
new /obj/effect/bhole(T)
/obj/machinery/power/rtg/antimatter_core/blob_act(obj/structure/blob/B)
+18 -12
View File
@@ -14,33 +14,36 @@
var/active = 0
var/locked = 0
var/drainratio = 1
rad_insulation = RAD_EXTREME_INSULATION //It sucks up the radiation. If you're standing behind it, you're pretty safe.
/obj/machinery/power/rad_collector/Initialize(mapload)
. = ..()
GLOB.rad_collectors += src
AddElement(/datum/element/climbable)
RegisterSignal(src, COMSIG_IN_RANGE_OF_IRRADIATION, PROC_REF(process_rads))
/obj/machinery/power/rad_collector/Destroy()
GLOB.rad_collectors -= src
UnregisterSignal(src, COMSIG_IN_RANGE_OF_IRRADIATION)
return ..()
/obj/machinery/power/rad_collector/process()
/obj/machinery/power/rad_collector/proc/process_rads(datum/source, datum/radiation_pulse_information/pulse_information)
SIGNAL_HANDLER
//so that we don't zero out the meter if the SM is processed first.
last_power = last_power_new
last_power_new = 0
if(P && active)
var/rads = SSradiation.get_rads_at_turf(get_turf(src))
if(rads)
receive_pulse(rads * 5) //Maths is hard
if(pulse_information)
var/amount_of_rads = pulse_information.strength
receive_pulse((amount_of_rads))
if(P)
if(P.air_contents.gas[GAS_PHORON] == 0)
investigate_log(span_red("out of fuel") + ".","singulo")
eject()
else
P.air_contents.adjust_gas(GAS_PHORON, -0.001*drainratio)
if(P.air_contents.gas[GAS_PHORON] == 0)
investigate_log(span_red("out of fuel") + ".","singulo")
eject()
else
P.air_contents.adjust_gas(GAS_PHORON, -0.0001*drainratio)
return
@@ -126,12 +129,15 @@
else
update_icons()
// Continuing here, SM giving us ~170 rads per pulse, a phoron canister full of 30 mols, and * 20 we get:
// 102000W per collector...So 10 collectors will give us ~1MW.
/obj/machinery/power/rad_collector/proc/receive_pulse(var/pulse_strength)
if(P && active)
var/power_produced = 0
power_produced = P.air_contents.gas[GAS_PHORON]*pulse_strength*20
add_avail(power_produced)
last_power_new = power_produced
if(power_produced)
add_avail(power_produced)
last_power_new = power_produced
return
return
@@ -148,13 +148,27 @@
/obj/machinery/particle_smasher/process()
if(!src.anchored) // Rapidly loses focus.
if(energy)
SSradiation.radiate(src, round(((src.energy-150)/50)*5,1))
radiation_pulse(
src,
max_range = 7,
threshold = RAD_HEAVY_INSULATION,
chance = round(((src.energy-150)/50)*5,1),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = energy * 0.1 //60 rads at max energy.
)
energy = max(0, energy - 30)
update_icon()
return
if(energy)
SSradiation.radiate(src, round(((src.energy-150)/50)*5,1))
radiation_pulse(
src,
max_range = 7,
threshold = RAD_HEAVY_INSULATION,
chance = round(((src.energy-150)/50)*5,1),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = energy * 0.1 //60 rads at max energy.
)
energy = CLAMP(energy - 5, 0, max_energy)
return
@@ -184,7 +198,14 @@
if(successful_craft)
visible_message(span_warning("\The [src] fizzles."))
if(prob(33)) // Why are you blasting it after it's already done!
SSradiation.radiate(src, 10 + round(src.energy / 60, 1))
radiation_pulse(
src,
max_range = 7,
threshold = RAD_HEAVY_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE + round(src.energy / 60, 1),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = energy * 0.1
)
energy = max(0, energy - 30)
update_icon()
return
+24 -4
View File
@@ -403,11 +403,16 @@ GLOBAL_LIST_BOILERPLATE(all_singularities, /obj/singularity)
/obj/singularity/proc/toxmob()
var/toxrange = 10
var/toxdamage = 4
var/radiation = 15
if (src.energy>200)
toxdamage = round(((src.energy-150)/50)*4,1)
radiation = round(((src.energy-150)/50)*5,1)
SSradiation.radiate(src, radiation) //Always radiate at max, so a decent dose of radiation is applied
radiation_pulse(
src,
max_range = 7,
threshold = RAD_EXTREME_INSULATION - 0.1,
chance = URANIUM_IRRADIATION_CHANCE + round(energy / 60, 1),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = 250
)
for(var/mob/living/M in view(toxrange, src.loc))
if(SEND_SIGNAL(M, COMSIG_CHECK_FOR_GODMODE) & COMSIG_GODMODE_CANCEL)
return 0 // Cancelled by a component
@@ -450,13 +455,28 @@ GLOBAL_LIST_BOILERPLATE(all_singularities, /obj/singularity)
to_chat(M, span_danger("You hear an unearthly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat."))
to_chat(M, span_danger("You don't even have a moment to react as you are reduced to ashes by the intense radiation."))
M.dust()
SSradiation.radiate(src, rand(energy))
radiation_pulse(
src,
max_range = 10,
threshold = RAD_EXTREME_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE * 8,
strength = 1000
)
return
/obj/singularity/proc/pulse()
for(var/obj/machinery/power/rad_collector/R in GLOB.rad_collectors)
if (get_dist(R, src) <= 15) //Better than using orange() every process.
R.receive_pulse(energy)
//Yes, this means rad collectors can double dip on the singulo, but you could always use the safer SM or tesla, so it gets a small buff.
radiation_pulse(
src,
max_range = 15,
threshold = RAD_EXTREME_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE * 8,
strength = energy * 0.25
)
/obj/singularity/proc/on_capture()
chained = 1
+54 -12
View File
@@ -170,12 +170,27 @@
var/turf/TS = get_turf(src) // The turf supermatter is on. SM being in a locker, exosuit, or other container shouldn't block it's effects that way.
if(!istype(TS))
return
radiation_pulse(
TS,
max_range = 255,
threshold = RAD_HEAVY_INSULATION,
chance = DETONATION_RADS,
strength = DETONATION_RADS * 5
)
var/list/affected_z = GetConnectedZlevels(TS.z)
// Effect 1: Radiation, weakening to all mobs on Z level
for(var/z in affected_z)
SSradiation.z_radiate(locate(1, 1, z), DETONATION_RADS, 1)
for(var/z_to_affect in affected_z)
var/turf/turf_to_hit = locate(TS.x, TS.y, z_to_affect)
if(turf_to_hit)
radiation_pulse(
turf_to_hit,
max_range = 255,
threshold = RAD_HEAVY_INSULATION,
chance = DETONATION_RADS,
strength = DETONATION_RADS * 5
)
for(var/mob/living/mob in GLOB.living_mob_list)
var/turf/TM = get_turf(mob)
@@ -398,7 +413,16 @@
if(!istype(l.glasses, /obj/item/clothing/glasses/meson) || l.is_incorporeal()) // VOREStation Edit - Only mesons can protect you! OR if they're not in the same plane of existence
l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / max(1,get_dist(l, src)) ) ) )
SSradiation.radiate(src, max(power * 1.5, 50) ) //Better close those shutters!
if(power)
// At a power mult of 0.025 for range, this means a 1000power SM (about normal) will reach 25 tiles and be putting off rad pulses of 500. With 0 protection, you have a 10% chance of getting hit.
radiation_pulse(
src,
max_range = CLAMP(max(round(power * 0.025), 3), 3, 50),
threshold = CLAMP(RAD_HEAVY_INSULATION - (power * 0.00025), 0.1, 1),
chance = round(power * 0.01),
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = round(power * 0.5)
)
power -= (power/DECAY_FACTOR)**3 //energy losses due to radiation
@@ -509,8 +533,13 @@
span_warning("The unearthly ringing subsides and you notice you have new radiation burns."), 2)
else
l.show_message(span_warning("You hear an uneartly ringing and notice your skin is covered in fresh radiation burns."), 2)
var/rads = 500
SSradiation.radiate(src, rads)
radiation_pulse(
src,
max_range = 5,
threshold = RAD_HEAVY_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
strength = 200
)
/proc/supermatter_pull(var/atom/target, var/pull_range = 255, var/pull_power = STAGE_FIVE)
for(var/atom/A in range(pull_range, target))
@@ -547,18 +576,31 @@
desc = "The shattered remains of a supermatter shard plinth. It doesn't look safe to be around."
icon = 'icons/obj/supermatter.dmi'
icon_state = "darkmatter_broken"
var/last_event = 0
/// Mutex to prevent infinite recursion when propagating radiation pulses
var/active = null
/obj/item/broken_sm/Initialize(mapload)
. = ..()
message_admins("Broken SM shard created at ([x],[y],[z] - <A href='byond://?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
START_PROCESSING(SSobj, src)
/obj/item/broken_sm/process()
SSradiation.radiate(src, 50)
/obj/item/broken_sm/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/broken_sm/proc/radiate()
SIGNAL_HANDLER
if(active)
return
if(world.time <= last_event + 1.5 SECONDS)
return
active = TRUE
radiation_pulse(
src,
max_range = 5,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = 25
)
last_event = world.time
active = FALSE
#undef POWER_FACTOR
#undef DECAY_FACTOR
+8 -2
View File
@@ -166,8 +166,14 @@
icon_scale_y = 2
var/rad_power = 50
/obj/item/projectile/arc/radioactive/on_impact(turf/T)
SSradiation.radiate(T, rad_power)
/obj/item/projectile/arc/radioactive/on_impact(turf/T) //This means you can shoot a rad collector to generate power...Might need to be adjusted.
radiation_pulse(
T,
max_range = 3,
threshold = RAD_LIGHT_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
strength = rad_power
)
// Blob mortar
/obj/item/projectile/arc/spore
-73
View File
@@ -1,73 +0,0 @@
// Describes a point source of radiation. Created either in response to a pulse of radiation, or over an irradiated atom.
// Sources will decay over time, unless something is renewing their power!
/datum/radiation_source
var/turf/source_turf // Location of the radiation source.
var/rad_power // Strength of the radiation being emitted.
var/decay = TRUE // True for automatic decay. False if owner promises to handle it (i.e. supermatter)
var/respect_maint = FALSE // True for not affecting RAD_SHIELDED areas.
var/flat = FALSE // True for power falloff with distance.
var/range // Cached maximum range, used for quick checks against mobs.
/datum/radiation_source/Destroy()
SSradiation.sources -= src
if(SSradiation.sources_assoc[src.source_turf] == src)
SSradiation.sources_assoc -= src.source_turf
src.source_turf = null
. = ..()
/datum/radiation_source/proc/update_rad_power(var/new_power = null)
if(new_power == null || new_power == rad_power)
return // No change
else if(new_power <= CONFIG_GET(number/radiation_lower_limit))
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
/turf
var/cached_rad_resistance = 0
/turf/proc/calc_rad_resistance()
cached_rad_resistance = 0
for(var/obj/O in src.contents)
if(O.rad_resistance) //Override
cached_rad_resistance += O.rad_resistance
else if(O.density) //So open doors don't get counted
var/datum/material/M = O.get_material()
if(!M) continue
cached_rad_resistance += (M.weight + M.radiation_resistance) / CONFIG_GET(number/radiation_material_resistance_divisor)
// Looks like storing the contents length is meant to be a basic check if the cache is stale due to items enter/exiting. Better than nothing so I'm leaving it as is. ~Leshana
SSradiation.resistance_cache[src] = (length(contents) + 1)
return
/turf/simulated/wall/calc_rad_resistance()
SSradiation.resistance_cache[src] = (length(contents) + 1)
var/temp_rad_resistance
temp_rad_resistance += material.weight + material.radiation_resistance
if(reinf_material)
temp_rad_resistance += reinf_material.weight + reinf_material.radiation_resistance
cached_rad_resistance = (density ? (temp_rad_resistance) / CONFIG_GET(number/radiation_material_resistance_divisor) : 0)
return
/turf/simulated/mineral/calc_rad_resistance()
if(!density)
return ..()
SSradiation.resistance_cache[src] = (length(contents) + 1)
cached_rad_resistance = 60 //Three times that of a steel wall. Rock is less dense than steel, but this is assuming that a normal wall isn't just solid steel all the way through like rock turfs are.
return
// If people expand the system, this may be useful. Here as a placeholder until then
/atom/proc/rad_act(var/severity)
return 1
/mob/living/rad_act(var/severity)
if(severity && !isbelly(loc)) //eaten mobs are made immune to radiation //VOREStation Edit
src.apply_effect(severity, IRRADIATE, src.getarmor(null, "rad"))
for(var/atom/I in src)
I.rad_act(severity)
return
+2
View File
@@ -70,6 +70,8 @@
total_volume = 0
for(var/datum/reagent/R in reagent_list)
if(R.volume < MINIMUM_CHEMICAL_VOLUME)
if(isliving(R.holder.my_atom))
R.on_mob_end_metabolize(R.holder.my_atom, src)
del_reagent(R.id)
else
total_volume += R.volume
@@ -46,6 +46,9 @@
var/wiki_flag = 0 // Bitflags for secret/food/drink reagent sorting
var/supply_conversion_value = null
var/industrial_use = null // unique description for export off station
/// A list of traits to apply while the reagent is being metabolized.
var/list/metabolized_traits
var/coolant_modifier = -0.5 // this is multiplied by the volume of the reagent. Most things are not good coolant. EX: Water is 1, coolant is 2. -1 would be a bad reagent for cooling.
@@ -186,6 +189,7 @@
affect_ingest(M, alien, removed * ingest_abs_mult)
if(CHEM_TOUCH)
affect_touch(M, alien, removed)
on_mob_metabolize(M, location)
if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH || can_overdose_touch))
overdose(M, alien, removed)
if(M.species.allergens & allergen_type) //uhoh, we can't handle this!
@@ -241,3 +245,14 @@
/// Called by [/datum/reagents/proc/conditional_update]
/datum/reagent/proc/on_update(atom/A)
return
/datum/reagent/proc/on_mob_metabolize(mob/living/affected_mob, datum/reagents/metabolism/location)
SHOULD_CALL_PARENT(TRUE)
if(metabolized_traits)
affected_mob.add_traits(metabolized_traits, "metabolize_location:[location]reagent:[type]")
/// Called when this reagent stops being metabolized (due to running out)
/// Has the args 'affected_mob' and 'location' which allows us to remove any traits that is only being added by that reagent holder location. I.e stomach, bloodstream, dermal, etc.
/datum/reagent/proc/on_mob_end_metabolize(mob/living/affected_mob, datum/reagents/location)
SHOULD_CALL_PARENT(TRUE)
REMOVE_TRAITS_IN(affected_mob, "metabolize_location:[location]reagent:[type]")
@@ -4132,6 +4132,19 @@
allergen_type = ALLERGEN_FRUIT|ALLERGEN_GRAINS //Made from vodka(grains) and orange juice(fruit)
/datum/reagent/ethanol/screwdrivercocktail/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, metabolization_ratio)
. = ..()
// var/obj/item/organ/internal/liver/liver = drinker.internal_organs_by_name[O_LIVER]
// if(HAS_TRAIT(liver, TRAIT_ENGINEER_METABOLISM))
ADD_TRAIT(drinker, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
if (HAS_TRAIT(drinker, TRAIT_IRRADIATED))
if(drinker.adjustToxLoss(-2 * metabolization_ratio * seconds_per_tick))
return //UPDATE_MOB_HEALTH
/datum/reagent/ethanol/screwdrivercocktail/on_mob_end_metabolize(mob/living/drinker)
. = ..()
REMOVE_TRAIT(drinker, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
/datum/reagent/ethanol/silencer
name = REAGENT_SILENCER
id = REAGENT_ID_SILENCER
@@ -118,6 +118,7 @@
scannable = SCANNABLE_BENEFICIAL
supply_conversion_value = REFINERYEXPORT_VALUE_COMMON
industrial_use = REFINERYEXPORT_REASON_DRUG
metabolized_traits = list(TRAIT_HALT_RADIATION_EFFECTS)
/datum/reagent/prussian_blue/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
+1 -1
View File
@@ -1098,7 +1098,7 @@
industrial_use = REFINERYEXPORT_REASON_BIOHAZARD
/datum/reagent/irradiated_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
SSradiation.radiate(get_turf(M), 20) // Irradiate people around you.
//SSradiation.radiate(get_turf(M), 20) // Irradiate people around you. //TODO
M.radiation = max(M.radiation + 5 * removed, 0) // Irradiate you. Because it's inside you.
/datum/reagent/neurophage_nanites
@@ -24,7 +24,7 @@
// Station Suits
/datum/design_techweb/mechfab/modsuit/eva_controller
name = "EVA Suit Control Module"
desc = "An engineering Hardsuit featuring a visor with welding protection, iommunity to radiation, and insulated gauntlets. It is well insulated against the heat."
desc = "An engineering Hardsuit featuring a visor with welding protection, immunity to radiation, and insulated gauntlets. It is well insulated against the heat."
id = "eva_rig_module"
materials = list(MAT_PLASTEEL = 16000, MAT_GOLD = 3000, MAT_GRAPHITE = 4500, MAT_OSMIUM = 1000, MAT_PLASTIC = 4500, MAT_LEAD = 2000, MAT_STEEL = 2000)
build_path = /obj/item/rig/eva
@@ -21,7 +21,14 @@
if(istype(holder, /obj/item/anobattery))
holder = holder.loc
if(holder)
SSradiation.flat_radiate(holder, radiation_amount, src.effectrange)
radiation_pulse(
holder,
max_range = effectrange,
threshold = RAD_LIGHT_INSULATION,
chance = chargelevelmax * 0.5,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = chargelevelmax * 0.5
)
return 1
/datum/artifact_effect/radiate/DoEffectPulse()
@@ -29,5 +36,11 @@
if(istype(holder, /obj/item/anobattery))
holder = holder.loc
if(holder)
SSradiation.radiate(holder, ((radiation_amount * 3) * (sqrt(src.effectrange))))
radiation_pulse(
holder,
max_range = effectrange,
threshold = RAD_LIGHT_INSULATION,
chance = chargelevelmax,
strength = chargelevelmax * 2,
)
return 1
+31 -2
View File
@@ -910,7 +910,35 @@
description_info = "When injected with phoron, this extract creates a single radioactive pulse. When injected with blood, this extract creates a radioactive glob. When injected with water \
this extract creates some radium. When injected with slime jelly, this extract creates some uranium."
slime_type = /mob/living/simple_mob/slime/xenobio/green
var/last_event = 0
/// Mutex to prevent infinite recursion when propagating radiation pulses
var/active = null
/obj/item/slime_extract/green/process()
radiate()
..()
/obj/item/slime_extract/green/proc/radiate()
SIGNAL_HANDLER
if(active)
return
if(world.time <= last_event + 1.5 SECONDS)
return
active = TRUE
radiation_pulse(
src,
max_range = 5,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = 50
)
last_event = world.time
active = FALSE
/obj/item/slime_extract/green/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/datum/decl/chemical_reaction/instant/slime/green_radpulse
name = "Slime Radiation Pulse"
@@ -924,8 +952,9 @@
playsound(holder.my_atom, 'sound/effects/phasein.ogg', 75, 1)
holder.my_atom.visible_message(span_danger("\The [holder.my_atom] begins to vibrate violently!"))
spawn(5 SECONDS)
SSradiation.flat_radiate(src, 30, 7, TRUE)
..()
if(!QDELETED(holder.my_atom) && istype(holder.my_atom, /obj/item/slime_extract/green))
START_PROCESSING(SSobj, src)
/datum/decl/chemical_reaction/instant/slime/green_emitter
+22 -1
View File
@@ -168,6 +168,9 @@
light_power = 0.4
light_range = 2
w_class = ITEMSIZE_TINY
var/last_event = 0
/// Mutex to prevent infinite recursion when propagating radiation pulses
var/active = null
/obj/item/slime_irradiator/Initialize(mapload)
. = ..()
@@ -175,7 +178,25 @@
set_light(light_range, light_power, light_color)
/obj/item/slime_irradiator/process()
SSradiation.radiate(src, 5)
radiate()
/obj/item/slime_irradiator/proc/radiate()
SIGNAL_HANDLER
if(active)
return
if(world.time <= last_event + 1.5 SECONDS)
return
active = TRUE
radiation_pulse(
src,
max_range = 5,
threshold = RAD_MEDIUM_INSULATION,
chance = URANIUM_IRRADIATION_CHANCE,
minimum_exposure_time = URANIUM_RADIATION_MINIMUM_EXPOSURE_TIME,
strength = 25
)
last_event = world.time
active = FALSE
/obj/item/slime_irradiator/Destroy()
STOP_PROCESSING(SSobj, src)