Files
Bubberstation/code/controllers/subsystem/radiation.dm
SkyratBot e90627be0e [MIRROR] Modernizing Radiation -- TL;DR: Radiation is now a status effect healed by tox healing, and contamination is removed [MDB IGNORE] (#9176)
* Modernizing Radiation -- TL;DR: Radiation is now a status effect healed by tox healing, and contamination is removed

* Fixing conflicts

* Makes it compile, yeet all the RAD armor from everywhere (thanks RegEx!)

* Removing more lingering rad armor (woo)

* Damnit powerarmors

* Bye bye rad collectors!

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
2021-11-02 10:36:46 -04:00

119 lines
3.8 KiB
Plaintext

SUBSYSTEM_DEF(radiation)
name = "Radiation"
flags = SS_BACKGROUND | SS_NO_INIT
wait = 0.5 SECONDS
/// A list of radiation sources (/datum/radiation_pulse_information) that have yet to process.
/// Do not interact with this directly, use `radiation_pulse` instead.
var/list/datum/radiation_pulse_information/processing = list()
/datum/controller/subsystem/radiation/fire(resumed)
while (processing.len)
var/datum/radiation_pulse_information/pulse_information = popleft(processing)
var/datum/weakref/source_ref = pulse_information.source_ref
var/atom/source = source_ref.resolve()
if (isnull(source))
continue
pulse(source, pulse_information)
if (MC_TICK_CHECK)
return
/datum/controller/subsystem/radiation/stat_entry(msg)
msg = "[msg] | Pulses: [processing.len]"
return ..()
/datum/controller/subsystem/radiation/proc/pulse(atom/source, datum/radiation_pulse_information/pulse_information)
var/list/cached_rad_insulations = list()
for (var/atom/movable/target in range(pulse_information.max_range, source))
if (!can_irradiate_basic(target))
continue
var/current_insulation = 1
for (var/turf/turf_in_between in get_line(source, target) - get_turf(source))
var/insulation = cached_rad_insulations[turf_in_between]
if (isnull(insulation))
insulation = turf_in_between.rad_insulation
for (var/atom/on_turf as anything in turf_in_between.contents)
insulation *= on_turf.rad_insulation
cached_rad_insulations[turf_in_between] = insulation
current_insulation *= insulation
if (current_insulation <= pulse_information.threshold)
break
SEND_SIGNAL(target, COMSIG_IN_RANGE_OF_IRRADIATION, pulse_information, current_insulation)
// Check a second time, because of TRAIT_BYPASS_EARLY_IRRADIATED_CHECK
if (HAS_TRAIT(target, TRAIT_IRRADIATED))
continue
if (current_insulation <= pulse_information.threshold)
continue
var/irradiation_result = SEND_SIGNAL(target, COMSIG_IN_THRESHOLD_OF_IRRADIATION, pulse_information)
if (irradiation_result & CANCEL_IRRADIATION)
continue
if (pulse_information.minimum_exposure_time && !(irradiation_result & SKIP_MINIMUM_EXPOSURE_TIME_CHECK))
target.AddComponent(/datum/component/radiation_countdown, pulse_information.minimum_exposure_time)
continue
if (!prob(pulse_information.chance))
continue
if (irradiate_after_basic_checks(target))
target.investigate_log("was irradiated by [source].", INVESTIGATE_RADIATION)
/// Will attempt to irradiate the given target, limited through IC means, such as radiation protected clothing.
/datum/controller/subsystem/radiation/proc/irradiate(atom/target)
if (!can_irradiate_basic(target))
return FALSE
irradiate_after_basic_checks()
return TRUE
/datum/controller/subsystem/radiation/proc/irradiate_after_basic_checks(atom/target)
PRIVATE_PROC(TRUE)
if (ishuman(target) && wearing_rad_protected_clothing(target))
return FALSE
target.AddComponent(/datum/component/irradiated)
return TRUE
/// Returns whether or not the target can be irradiated by any means.
/// Does not check for clothing.
/datum/controller/subsystem/radiation/proc/can_irradiate_basic(atom/target)
if (!CAN_IRRADIATE(target))
return FALSE
if (HAS_TRAIT(target, TRAIT_IRRADIATED) && !HAS_TRAIT(target, TRAIT_BYPASS_EARLY_IRRADIATED_CHECK))
return FALSE
if (HAS_TRAIT(target, TRAIT_RADIMMUNE))
return FALSE
return TRUE
/// Returns whether or not the human is covered head to toe in rad-protected clothing.
/datum/controller/subsystem/radiation/proc/wearing_rad_protected_clothing(mob/living/carbon/human/human)
for (var/obj/item/bodypart/limb as anything in human.bodyparts)
var/protected = FALSE
for (var/obj/item/clothing as anything in human.clothingonpart(limb))
if (HAS_TRAIT(clothing, TRAIT_RADIATION_PROTECTED_CLOTHING))
protected = TRUE
break
if (!protected)
return FALSE
return TRUE