diff --git a/beestation.dme b/beestation.dme
index 37800fc8047a9..7829a9ad6717d 100644
--- a/beestation.dme
+++ b/beestation.dme
@@ -547,7 +547,6 @@
#include "code\datums\position_point_vector.dm"
#include "code\datums\profiling.dm"
#include "code\datums\progressbar.dm"
-#include "code\datums\radiation_wave.dm"
#include "code\datums\recipe.dm"
#include "code\datums\ref.dm"
#include "code\datums\ruins.dm"
@@ -3518,7 +3517,6 @@
#include "code\modules\power\lighting\light_wallframes.dm"
#include "code\modules\power\singularity\anomaly.dm"
#include "code\modules\power\singularity\boh_tear.dm"
-#include "code\modules\power\singularity\collector.dm"
#include "code\modules\power\singularity\containment_field.dm"
#include "code\modules\power\singularity\emitter.dm"
#include "code\modules\power\singularity\field_generator.dm"
@@ -3529,6 +3527,7 @@
#include "code\modules\power\singularity\particle_accelerator\particle_emitter.dm"
#include "code\modules\power\supermatter\supermatter.dm"
#include "code\modules\power\supermatter\supermatter_delamination.dm"
+#include "code\modules\power\supermatter\supermatter_radiation.dm"
#include "code\modules\power\tesla\coil.dm"
#include "code\modules\power\tesla\energy_ball.dm"
#include "code\modules\power\tesla\generator.dm"
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index c0d55d51c3204..8e43ad7054c3b 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -54,7 +54,7 @@
switch(P.type)
if(/obj/projectile/energy/floramut)
if(prob(15))
- H.rad_act(rand(30,80))
+ H.adjustToxLoss(rand(3, 6))
H.Paralyze(100)
H.visible_message("[H] writhes in pain as [H.p_their()] vacuoles boil.", "You writhe in pain as your vacuoles boil!", "You hear the crunching of leaves.")
if(prob(80))
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
deleted file mode 100644
index 572611781c3dd..0000000000000
--- a/code/modules/power/singularity/collector.dm
+++ /dev/null
@@ -1,251 +0,0 @@
-// stored_energy += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
-#define RAD_COLLECTOR_EFFICIENCY 80 // radiation needs to be over this amount to get power
-#define RAD_COLLECTOR_COEFFICIENT 100
-#define RAD_COLLECTOR_STORED_OUT 0.04 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
-#define RAD_COLLECTOR_MINING_CONVERSION_RATE 0.0001 //This is gonna need a lot of tweaking to get right. This is the number used to calculate the conversion of watts to research points per process()
-#define RAD_COLLECTOR_OUTPUT min(stored_energy, (stored_energy*RAD_COLLECTOR_STORED_OUT)+1000) //Produces at least 1000 watts if it has more than that stored
-
-
-/obj/machinery/power/rad_collector
- name = "Radiation Collector Array"
- desc = "A device which uses Hawking Radiation and plasma to produce power."
- icon = 'icons/obj/singularity.dmi'
- icon_state = "ca"
- anchored = FALSE
- density = TRUE
- req_access = list(ACCESS_ENGINE_EQUIP)
-// use_power = NO_POWER_USE
- max_integrity = 350
- integrity_failure = 0.2
- circuit = /obj/item/circuitboard/machine/rad_collector
- rad_insulation = RAD_EXTREME_INSULATION
- var/obj/item/tank/internals/plasma/loaded_tank = null
- var/stored_energy = 0
- var/active = 0
- var/locked = FALSE
- var/drainratio = 0.5
- var/powerproduction_drain = 0.01
- var/bitcoinproduction_drain = 0.15
- var/bitcoinmining = FALSE
- var/obj/item/radio/radio
-
-/obj/machinery/power/rad_collector/Initialize(mapload)
- . = ..()
-
- radio = new(src)
- radio.keyslot = new /obj/item/encryptionkey/headset_eng
- radio.subspace_transmission = TRUE
- radio.canhear_range = 0
- radio.recalculateChannels()
-
-/obj/machinery/power/rad_collector/anchored/Initialize()
- . = ..()
- set_anchored(TRUE)
-
-/obj/machinery/power/rad_collector/Destroy()
- QDEL_NULL(radio)
- return ..()
-
-/obj/machinery/power/rad_collector/process(delta_time)
- if(!loaded_tank)
- return
- if(!bitcoinmining)
- if(loaded_tank.air_contents.get_moles(GAS_PLASMA) < 0.0001)
- investigate_log("out of fuel.", INVESTIGATE_ENGINES)
- playsound(src, 'sound/machines/ding.ogg', 50, 1)
- var/msg = "Plasma depleted, recommend replacing tank."
- radio.talk_into(src, msg, RADIO_CHANNEL_ENGINEERING)
- eject()
- else
- var/gasdrained = min(powerproduction_drain*drainratio*delta_time,loaded_tank.air_contents.get_moles(GAS_PLASMA))
- loaded_tank.air_contents.adjust_moles(GAS_PLASMA, -gasdrained)
- loaded_tank.air_contents.adjust_moles(GAS_TRITIUM, gasdrained)
- var/power_produced = RAD_COLLECTOR_OUTPUT
- add_avail(power_produced)
- stored_energy-=power_produced
- else if(is_station_level(z) && SSresearch.science_tech)
- if(!loaded_tank.air_contents.get_moles(GAS_TRITIUM) || !loaded_tank.air_contents.get_moles(GAS_O2))
- playsound(src, 'sound/machines/ding.ogg', 50, 1)
- eject()
- else
- var/gasdrained = bitcoinproduction_drain*drainratio*delta_time
- loaded_tank.air_contents.adjust_moles(GAS_TRITIUM, -gasdrained)
- loaded_tank.air_contents.adjust_moles(GAS_O2, -gasdrained)
- loaded_tank.air_contents.adjust_moles(GAS_CO2, gasdrained*2)
- var/bitcoins_mined = RAD_COLLECTOR_OUTPUT
- var/datum/bank_account/D = SSeconomy.get_budget_account(ACCOUNT_ENG_ID)
- if(D)
- D.adjust_money(bitcoins_mined*RAD_COLLECTOR_MINING_CONVERSION_RATE)//about 1500 credits per minute with 2 emitters and 6 collectors with stock parts
- SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, bitcoins_mined*RAD_COLLECTOR_MINING_CONVERSION_RATE)//about 1300 points per minute with the above set up
- SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DISCOVERY, bitcoins_mined*RAD_COLLECTOR_MINING_CONVERSION_RATE)//same here
- stored_energy-=bitcoins_mined
-
-/obj/machinery/power/rad_collector/interact(mob/user)
- if(anchored)
- if(!src.locked)
- toggle_power()
- user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
- "You turn the [src.name] [active? "on":"off"].")
- var/fuel = loaded_tank?.air_contents.get_moles(GAS_PLASMA)
- investigate_log("turned [active?"on":"off"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"It is empty"].", INVESTIGATE_ENGINES)
- return
- else
- to_chat(user, "The controls are locked!")
- return
-
-/obj/machinery/power/rad_collector/can_be_unfasten_wrench(mob/user, silent)
- if(loaded_tank)
- if(!silent)
- to_chat(user, "Remove the plasma tank first!")
- return FAILED_UNFASTEN
- return ..()
-
-/obj/machinery/power/rad_collector/set_anchored(anchorvalue)
- . = ..()
- if(isnull(.))
- return //no need to process if we didn't change anything.
- if(anchorvalue)
- connect_to_network()
- else
- disconnect_from_network()
-
-/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/tank/internals/plasma))
- if(!anchored)
- to_chat(user, "[src] needs to be secured to the floor first!")
- return TRUE
- if(loaded_tank)
- to_chat(user, "There's already a plasma tank loaded!")
- return TRUE
- if(panel_open)
- to_chat(user, "Close the maintenance panel first!")
- return TRUE
- if(!user.transferItemToLoc(W, src))
- return
- loaded_tank = W
- update_icon()
- else if(W.GetID())
- if(allowed(user))
- if(active)
- locked = !locked
- to_chat(user, "You [locked ? "lock" : "unlock"] the controls.")
- else
- to_chat(user, "The controls can only be locked when \the [src] is active!")
- else
- to_chat(user, "Access denied.")
- return TRUE
- else
- return ..()
-
-/obj/machinery/power/rad_collector/wrench_act(mob/living/user, obj/item/I)
- default_unfasten_wrench(user, I)
- return TRUE
-
-/obj/machinery/power/rad_collector/screwdriver_act(mob/living/user, obj/item/I)
- if(..())
- return TRUE
- if(loaded_tank)
- to_chat(user, "Remove the plasma tank first!")
- else
- default_deconstruction_screwdriver(user, icon_state, icon_state, I)
- return TRUE
-
-/obj/machinery/power/rad_collector/crowbar_act(mob/living/user, obj/item/I)
- if(loaded_tank)
- if(locked)
- to_chat(user, "The controls are locked!")
- return TRUE
- eject()
- return TRUE
- if(default_deconstruction_crowbar(I))
- return TRUE
- to_chat(user, "There isn't a tank loaded!")
- return TRUE
-
-/obj/machinery/power/rad_collector/multitool_act(mob/living/user, obj/item/I)
- if(!is_station_level(z) && !SSresearch.science_tech)
- to_chat(user, "[src] isn't linked to a research system!")
- return TRUE
- if(locked)
- to_chat(user, "[src] is locked!")
- return TRUE
- if(active)
- to_chat(user, "[src] is currently active, producing [bitcoinmining ? "research points":"power"].")
- return TRUE
- bitcoinmining = !bitcoinmining
- to_chat(user, "You [bitcoinmining ? "enable":"disable"] the research point production feature of [src].")
- return TRUE
-
-/obj/machinery/power/rad_collector/return_analyzable_air()
- if(loaded_tank)
- return loaded_tank.return_analyzable_air()
- else
- return null
-
-/obj/machinery/power/rad_collector/examine(mob/user)
- . = ..()
- if(active)
- if(!bitcoinmining)
- // stored_energy is converted directly to watts every SSmachines.wait * 0.1 seconds.
- // Therefore, its units are joules per SSmachines.wait * 0.1 seconds.
- // So joules = stored_energy * SSmachines.wait * 0.1
- var/joules = stored_energy * SSmachines.wait * 0.1
- . += "[src]'s display states that it has stored [display_joules(joules)], and is processing [display_power(RAD_COLLECTOR_OUTPUT)]."
- else
- . += "[src]'s display states that it has stored a total of [stored_energy*RAD_COLLECTOR_MINING_CONVERSION_RATE], and is producing [RAD_COLLECTOR_OUTPUT*RAD_COLLECTOR_MINING_CONVERSION_RATE] research points per minute."
- else
- if(!bitcoinmining)
- . += "[src]'s display displays the words: \"Power production mode. Please insert Plasma. Use a multitool to change production modes.\""
- else
- . += "[src]'s display displays the words: \"Research point production mode. Please insert Tritium and Oxygen. Use a multitool to change production modes.\""
-
-/obj/machinery/power/rad_collector/obj_break(damage_flag)
- . = ..()
- if(.)
- eject()
-
-/obj/machinery/power/rad_collector/proc/eject()
- locked = FALSE
- var/obj/item/tank/internals/plasma/Z = src.loaded_tank
- if (!Z)
- return
- Z.forceMove(drop_location())
- Z.layer = initial(Z.layer)
- Z.plane = initial(Z.plane)
- src.loaded_tank = null
- if(active)
- toggle_power()
- else
- update_icon()
-
-/obj/machinery/power/rad_collector/rad_act(pulse_strength)
- . = ..()
- if(loaded_tank && active && pulse_strength > RAD_COLLECTOR_EFFICIENCY)
- stored_energy += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
-
-/obj/machinery/power/rad_collector/update_icon()
- cut_overlays()
- if(loaded_tank)
- add_overlay("ptank")
- if(machine_stat & (NOPOWER|BROKEN))
- return
- if(active)
- add_overlay("on")
-
-
-/obj/machinery/power/rad_collector/proc/toggle_power()
- active = !active
- if(active)
- icon_state = "ca_on"
- flick("ca_active", src)
- else
- icon_state = "ca"
- flick("ca_deactive", src)
- update_icon()
- return
-
-#undef RAD_COLLECTOR_EFFICIENCY
-#undef RAD_COLLECTOR_COEFFICIENT
-#undef RAD_COLLECTOR_STORED_OUT
-#undef RAD_COLLECTOR_MINING_CONVERSION_RATE
-#undef RAD_COLLECTOR_OUTPUT
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index ef3a9592a5ee5..09dfebf60f7a5 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -500,9 +500,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
power = clamp((removed.return_temperature() * temp_factor / T0C) * gasmix_power_ratio + power, 0, SUPERMATTER_MAXIMUM_ENERGY) //Total laser power plus an overload
- if(prob(50))
- last_rads = power * max(0, power_transmission_bonus * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + (pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) + (bzcomp * BZ_RADIOACTIVITY_MODIFIER))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%)
- radiation_pulse(src, last_rads)
+ emit_radiation()
if(bzcomp >= 0.4 && prob(30 * bzcomp))
src.fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick
@@ -734,14 +732,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
user.visible_message("A hideous sound echoes as [W] is ashed out on contact with \the [src]. That didn't seem like a good idea...")
playsound(src, 'sound/effects/supermatter.ogg', 150, 1)
Consume(W)
- radiation_pulse(src, 150, 4)
+ radiation_pulse(src, max_range = 3, threshold = 0.1, chance = 50)
return ..()
else
cig.light()
user.visible_message("As [user] lights \their [W] on \the [src], silence fills the room...",\
"Time seems to slow to a crawl as you touch \the [src] with \the [W].\n\The [W] flashes alight with an eerie energy as you nonchalantly lift your hand away from \the [src]. Damn.")
playsound(src, 'sound/effects/supermatter.ogg', 50, 1)
- radiation_pulse(src, 50, 3)
+ radiation_pulse(src, max_range = 1, threshold = 0, chance = 100)
return
if(istype(W, /obj/item/scalpel/supermatter))
var/obj/item/scalpel/supermatter/scalpel = W
@@ -764,7 +762,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
Consume(W)
playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1)
- radiation_pulse(src, 150, 4)
+ radiation_pulse(src, max_range = 3, threshold = 0.1, chance = 50)
/obj/machinery/power/supermatter_crystal/wrench_act(mob/user, obj/item/tool)
if (moveable)
@@ -825,14 +823,18 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
matter_power += 200
//Some poor sod got eaten, go ahead and irradiate people nearby.
- radiation_pulse(src, 3000, 2, TRUE)
+ radiation_pulse(src, max_range = 6, threshold = 0.3, chance = 30)
for(var/mob/living/L in range(10))
investigate_log("has irradiated [key_name(L)] after consuming [AM].", INVESTIGATE_ENGINES)
+ if (HAS_TRAIT(near_mob, TRAIT_RADIMMUNE) || issilicon(near_mob))
+ continue
+ if(ishuman(near_mob) && SSradiation.wearing_rad_protected_clothing(near_mob))
+ continue
if(L in viewers(get_turf(src)))
L.show_message("As \the [src] slowly stops resonating, you find your skin covered in new radiation burns.", 1,\
- "The unearthly ringing subsides and you notice you have new radiation burns.", MSG_AUDIBLE)
+ "The unearthly ringing subsides and you find your skin covered in new radiation burns.", MSG_AUDIBLE)
else
- L.show_message("You hear an unearthly ringing and notice your skin is covered in fresh radiation burns.", MSG_AUDIBLE)
+ L.show_message("An unearthly ringing and fills your ears, and you find your skin covered in new radiation burns.", MSG_AUDIBLE)
/obj/machinery/power/supermatter_crystal/proc/disengage_field()
if(QDELETED(src))
diff --git a/code/modules/power/supermatter/supermatter_delamination.dm b/code/modules/power/supermatter/supermatter_delamination.dm
index e426173eda3a1..dc60dff74c3c9 100644
--- a/code/modules/power/supermatter/supermatter_delamination.dm
+++ b/code/modules/power/supermatter/supermatter_delamination.dm
@@ -47,8 +47,8 @@
//Hilariously enough, running into a closet should make you get hit the hardest.
var/mob/living/carbon/human/H = mob
H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) )
- var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(L, src) + 1) )
- L.rad_act(rads)
+ if (get_dist(victim, src) <= DETONATION_RADIATION_RANGE)
+ SSradiation.irradiate(victim)
for(var/mob/M in GLOB.player_list)
if(M.get_virtual_z_level() == supermatter_z)
diff --git a/code/modules/power/supermatter/supermatter_radiation.dm b/code/modules/power/supermatter/supermatter_radiation.dm
new file mode 100644
index 0000000000000..546ec13f8f919
--- /dev/null
+++ b/code/modules/power/supermatter/supermatter_radiation.dm
@@ -0,0 +1,57 @@
+// Any power past this number will be clamped down
+#define MAX_ACCEPTED_POWER_OUTPUT 5000
+
+// At the highest power output, assuming no integrity changes, the threshold will be 0.
+#define THRESHOLD_EQUATION_SLOPE (-1 / MAX_ACCEPTED_POWER_OUTPUT)
+
+// The higher this number, the faster low integrity will drop threshold
+// I would've named this "power", but y'know. :P
+#define INTEGRITY_EXPONENTIAL_DEGREE 2
+
+// At INTEGRITY_MIN_NUDGABLE_AMOUNT, the power will be treated as, at most, INTEGRITY_MAX_POWER_NUDGE.
+// Any lower integrity will result in INTEGRITY_MAX_POWER_NUDGE.
+#define INTEGRITY_MAX_POWER_NUDGE 1500
+#define INTEGRITY_MIN_NUDGABLE_AMOUNT 0.7
+
+#define RADIATION_CHANCE_AT_FULL_INTEGRITY 0.03
+#define RADIATION_CHANCE_AT_ZERO_INTEGRITY 0.4
+#define CHANCE_EQUATION_SLOPE (RADIATION_CHANCE_AT_ZERO_INTEGRITY - RADIATION_CHANCE_AT_FULL_INTEGRITY)
+
+/obj/machinery/power/supermatter_crystal/proc/emit_radiation()
+ // As power goes up, rads go up.
+ // A standard N2 SM seems to produce a value of around 1,500.
+ var/power_factor = min(power, MAX_ACCEPTED_POWER_OUTPUT)
+
+ var/integrity = 1 - CLAMP01(damage / explosion_point)
+
+ // When integrity goes down, the threshold (from an observable point of view, rads) go up.
+ // However, the power factor must go up as well, otherwise turning off the emitters
+ // on a delaminating SM would stop radiation from escaping.
+ // To fix this, lower integrities raise the power factor to a minimum.
+ var/integrity_power_nudge = LERP(INTEGRITY_MAX_POWER_NUDGE, 0, CLAMP01((integrity - INTEGRITY_MIN_NUDGABLE_AMOUNT) / (1 - INTEGRITY_MIN_NUDGABLE_AMOUNT)))
+
+ power_factor = max(power_factor, integrity_power_nudge)
+
+ // At the "normal" N2 power output (with max integrity), this is 0.7, which is enough to be stopped
+ // by the walls or the radation shutters.
+ // As integrity does down, rads go up.
+ var/threshold = (THRESHOLD_EQUATION_SLOPE * power_factor + 1) ** ((1 / integrity) ** INTEGRITY_EXPONENTIAL_DEGREE)
+
+ // Calculating chance is done entirely on integrity, so that actively delaminating SMs feel more dangerous
+ var/chance = (CHANCE_EQUATION_SLOPE * (1 - integrity)) + RADIATION_CHANCE_AT_FULL_INTEGRITY
+
+ radiation_pulse(
+ src,
+ max_range = 8,
+ threshold = threshold,
+ chance = chance * 100,
+ )
+
+#undef CHANCE_EQUATION_SLOPE
+#undef INTEGRITY_EXPONENTIAL_DEGREE
+#undef INTEGRITY_MAX_POWER_NUDGE
+#undef INTEGRITY_MIN_NUDGABLE_AMOUNT
+#undef MAX_ACCEPTED_POWER_OUTPUT
+#undef RADIATION_CHANCE_AT_FULL_INTEGRITY
+#undef RADIATION_CHANCE_AT_ZERO_INTEGRITY
+#undef THRESHOLD_EQUATION_SLOPE
diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm
index 2e82919cbcfbe..5c92637800082 100644
--- a/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -150,11 +150,11 @@
switch(fail_tick)
if(0 to 200)
fail_tick += (2*(fail_chance))
- M.rad_act(40)
+ M.adjustFireLoss(3)
to_chat(M, "Your [name] feels warmer.")
if(201 to INFINITY)
SSobj.processing.Remove(src)
- M.rad_act(80)
+ M.adjustFireLoss(10)
reactor_overloaded = TRUE
to_chat(M, "Your [name]'s reactor overloads!")
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index f1ee75c92e7c0..af3e0aee3ae2f 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -137,7 +137,6 @@
var/paralyze = 0
var/immobilize = 0
var/unconscious = 0
- var/irradiate = 0
var/stutter = 0
var/slur = 0
var/eyeblur = 0
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index 54781b9044663..525656c994730 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -66,7 +66,6 @@
name = "\improper X-ray beam"
icon_state = "xray"
damage = 15
- irradiate = 300
range = 15
armour_penetration = 60
pass_flags = PASSTABLE | PASSTRANSPARENT | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINE | PASSSTRUCTURE | PASSDOORS
diff --git a/code/modules/projectiles/projectile/energy/misc.dm b/code/modules/projectiles/projectile/energy/misc.dm
index 79ee634a3e66a..cb5009c7981cf 100644
--- a/code/modules/projectiles/projectile/energy/misc.dm
+++ b/code/modules/projectiles/projectile/energy/misc.dm
@@ -3,12 +3,20 @@
icon_state = "declone"
damage = 20
damage_type = CLONE
- irradiate = 100
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
+ /// The chance to be irradiated on hit
+ var/radiation_chance = 30
+
+/obj/projectile/energy/declone/on_hit(atom/target, blocked, pierce_hit)
+ if (ishuman(target) && prob(radiation_chance))
+ radiation_pulse(target, max_range = 0, threshold = RAD_FULL_INSULATION)
+
+ ..()
+
/obj/projectile/energy/declone/weak
damage = 9
- irradiate = 30
+ radiation_chance = 10
/obj/projectile/energy/dart //ninja throwing dart
name = "dart"
diff --git a/code/modules/projectiles/projectile/energy/nuclear_particle.dm b/code/modules/projectiles/projectile/energy/nuclear_particle.dm
index 98eb16acb14b7..5ccb53ede786e 100644
--- a/code/modules/projectiles/projectile/energy/nuclear_particle.dm
+++ b/code/modules/projectiles/projectile/energy/nuclear_particle.dm
@@ -5,7 +5,6 @@
pass_flags = PASSTABLE | PASSTRANSPARENT | PASSGRILLE
damage = 10
damage_type = TOX
- irradiate = 2500 //enough to knockdown and induce vomiting
speed = 0.4
hitsound = 'sound/weapons/emitter2.ogg'
impact_type = /obj/effect/projectile/impact/xray
@@ -52,6 +51,12 @@
name = "impossibly strong nuclear particle"
damage = 30
+/obj/projectile/energy/nuclear_particle/on_hit(atom/target, blocked, pierce_hit)
+ if (ishuman(target))
+ radiation_pulse(target, max_range = 0, threshold = RAD_FULL_INSULATION)
+
+ ..()
+
/atom/proc/fire_nuclear_particle(angle = rand(0,360), customize = FALSE, custompower = 1e12) //used by fusion to fire random nuclear particles. Fires one particle in a random direction.
var/obj/projectile/energy/nuclear_particle/P = new /obj/projectile/energy/nuclear_particle(src)
if(customize)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 6b483e41f06d7..45679c14d1506 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -256,10 +256,6 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "The glass contain wodka. Xynta."
shot_glass_icon_state = "shotglassclear"
-/datum/reagent/consumable/ethanol/vodka/on_mob_life(mob/living/carbon/M)
- M.radiation = max(M.radiation-2,0)
- return ..()
-
/datum/reagent/consumable/ethanol/bilk
name = "Bilk"
description = "This appears to be beer mixed with milk. Disgusting."
@@ -564,7 +560,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_life(mob/living/carbon/M)
if(M.mind && (M.mind.assigned_role in list(JOB_NAME_STATIONENGINEER, JOB_NAME_ATMOSPHERICTECHNICIAN, JOB_NAME_CHIEFENGINEER))) //Engineers lose radiation poisoning at a massive rate.
- M.radiation = max(M.radiation - 25, 0)
+ ADD_TRAIT(M, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
+ if (HAS_TRAIT(M, TRAIT_IRRADIATED))
+ M.adjustToxLoss(-2 * REM * delta_time)
+
+ return ..()
+
+/datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_end_metabolize(mob/living/L)
+ REMOVE_TRAIT(L, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
return ..()
/datum/reagent/consumable/ethanol/booger
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 2662845dc91bc..c03c7ee618284 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -565,27 +565,43 @@
/datum/reagent/medicine/potass_iodide
name = "Potassium Iodide"
- description = "Efficiently restores low radiation damage."
+ description = "Heals low toxin damage while the patient is irradiated, and will halt the damaging effects of radiation."
reagent_state = LIQUID
color = "#BAA15D"
chem_flags = CHEMICAL_RNG_GENERAL | CHEMICAL_RNG_FUN | CHEMICAL_RNG_BOTANY | CHEMICAL_GOAL_BOTANIST_HARVEST
metabolization_rate = 2 * REAGENTS_METABOLISM
+/datum/reagent/medicine/potass_iodide/on_mob_metabolize(mob/living/L)
+ . = ..()
+ ADD_TRAIT(L, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
+
+/datum/reagent/medicine/potass_iodide/on_mob_end_metabolize(mob/living/L)
+ REMOVE_TRAIT(L, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
+ return ..()
+
/datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/carbon/M)
- if(M.radiation > 0)
- M.radiation -= min(M.radiation, 8)
+ if (HAS_TRAIT(M, TRAIT_IRRADIATED))
+ M.adjustToxLoss(-1 * REM * delta_time)
+
..()
/datum/reagent/medicine/pen_acid
name = "Pentetic Acid"
- description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body."
+ description = "Reduces massive amounts of toxin damage while purging other chemicals from the body."
reagent_state = LIQUID
color = "#E6FFF0"
chem_flags = CHEMICAL_RNG_GENERAL | CHEMICAL_RNG_FUN | CHEMICAL_RNG_BOTANY | CHEMICAL_GOAL_CHEMIST_USEFUL_MEDICINE
metabolization_rate = 0.5 * REAGENTS_METABOLISM
+/datum/reagent/medicine/pen_acid/on_mob_metabolize(mob/living/L)
+ . = ..()
+ ADD_TRAIT(L, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
+
+/datum/reagent/medicine/pen_acid/on_mob_end_metabolize(mob/living/L)
+ REMOVE_TRAIT(L, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
+ return ..()
+
/datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M)
- M.radiation -= max(M.radiation-RAD_MOB_SAFE, 0)/50
M.adjustToxLoss(-2*REM, 0)
for(var/datum/reagent/R in M.reagents.reagent_list)
if(R != src)
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 6fad1eae6381b..5ea0c4c58356b 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -10,7 +10,6 @@
resistance_flags = FIRE_PROOF
interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON
obj_flags = CAN_BE_HIT | USES_TGUI
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
diff --git a/code/modules/recycling/disposal/holder.dm b/code/modules/recycling/disposal/holder.dm
index 17c6872425561..f93eb7b1c9c79 100644
--- a/code/modules/recycling/disposal/holder.dm
+++ b/code/modules/recycling/disposal/holder.dm
@@ -9,7 +9,6 @@
dir = NONE
var/obj/structure/disposalpipe/last_pipe
var/obj/structure/disposalpipe/current_pipe
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
var/datum/gas_mixture/gas // gas used to flush, will appear at exit point
var/active = FALSE // true if the holder is moving, otherwise inactive
var/count = 1000 // can travel 1000 steps before going inactive (in case of loops)
diff --git a/code/modules/recycling/disposal/outlet.dm b/code/modules/recycling/disposal/outlet.dm
index 7cff1fcfd4fa4..11cdcc0239a92 100644
--- a/code/modules/recycling/disposal/outlet.dm
+++ b/code/modules/recycling/disposal/outlet.dm
@@ -6,7 +6,6 @@
icon_state = "outlet"
density = TRUE
anchored = TRUE
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
var/active = FALSE
var/turf/target // this will be where the output objects are 'thrown' to.
var/obj/structure/disposalpipe/trunk/trunk // the attached pipe trunk