Files
Batrachophreno eebb8b971c Materials Repath (#22388)
Soft-ish port of https://github.com/NebulaSS13/Nebula/pull/540. Except
we call them singletons.

Repaths all materials as singletons instead of datums, and replaces
material defines from strings to paths so that we can just run
GET_SINGLETON instead of needing to use SSMaterials. This is Step One.

This PR has no player-facing changes.

changes:
  - refactor: "Repaths /material to /singleton/material."
- refactor: "Replaces all material string defines to path defines,
replacing SSmaterials procs w/ GET_SINGLETON instead."
- refactor: "Removes all material var edited objects from all maps,
adding new presets where necessary."
- refactor: "Updates recipes unit test to run all recipes against all
material singletons."

---------

Signed-off-by: Batrachophreno <Batrochophreno@gmail.com>
Co-authored-by: kano-dot <bhutanlikanoxy@gmail.com>
2026-07-10 18:45:58 +00:00

97 lines
3.5 KiB
Plaintext

// 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
/// Location of the radiation source.
var/turf/source_turf
/// Strength of the radiation being emitted.
var/rad_power
/// True for automatic decay. False if owner promises to handle it (i.e. Supermatter, INDRA, etc.)
var/decay = TRUE
///Added to the base decay rate of a source, for sudden spikes of radiation that don't persist as long
var/accelerated_decay_rate
/// True for not affecting AREA_FLAG_RAD_SHIELDED areas.
var/respect_rad_shielding = FALSE
/// True for power falloff with distance.
var/flat = FALSE
/// Cached maximum range, used for quick checks against mobs.
var/range
/datum/radiation_source/New(source_turf, rad_power, decay = TRUE)
src.source_turf = source_turf
src.rad_power = rad_power
src.decay = decay
/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
. = ..()
/**
* Initialization handling decaying sources. Decrease by RADIATION_DECAY_RATE per SSradiation.fire() in latter cases.
*/
/datum/radiation_source/proc/update_rad_power(new_power = null)
if(new_power == null || new_power == rad_power)
return // No change
else if(new_power <= RADIATION_LOWER_LIMIT)
qdel(src) // Decayed to nothing
else
rad_power = new_power
if(!flat)
// R = rad_power / dist**2 - Solve for dist
range = min(round(sqrt(rad_power / RADIATION_LOWER_LIMIT)), 31)
/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_modifier <= 0) && O.density)
var/singleton/material/M = O.get_material()
if(!M) continue
cached_rad_resistance += (M.weight * O.rad_resistance_modifier) / 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)
/turf/simulated/wall/calc_rad_resistance()
SSradiation.resistance_cache[src] = (length(contents) + 1)
cached_rad_resistance = (density ? material.weight / RADIATION_MATERIAL_RESISTANCE_DIVISOR : 0)
/**
* Retrieves the atom's current radiation level. By default, this will return `loc.get_rads()`.
*
* Returns integer.
*/
/atom/proc/get_rads()
if(loc)
return loc.get_rads()
return 0
/turf/get_rads()
return SSradiation.get_rads_at_turf(src)
/**
* Called when radiation affects the atom.
*
* * severity - The amount of radiation being applied. Also see RAD_LEVEL_*.
*
* Returns boolean
*/
/atom/proc/rad_act(severity)
return 1
/**
* Called when radiation affects a /mob/living.
*
* * severity - The amount of radiation being applied. Anything over RAD_LEVEL_VERY_LOW will deal [severity] dispersed damage and run rad_act to everything in it.
*
* Returns boolean
*/
/mob/living/rad_act(severity)
if(severity > RAD_LEVEL_VERY_LOW)
var/normal_armour_piercing = severity - (severity / 11) //As damage is split across all 11 limbs, this is subtracted from the armour value to replicate one big hit.
apply_damage(severity, DAMAGE_RADIATION, damage_flags = DAMAGE_FLAG_DISPERSED | DAMAGE_FLAG_IGNORE_PROSTHETICS, armor_pen = normal_armour_piercing) //Metal body parts do not contribute to radiation dose.
for(var/atom/I in src)
I.rad_act(severity)