Files
Bubberstation/code/__HELPERS/radiation.dm
Tim 4a70568e24 Being exposed to radioactive reagents causes irradiate effects (#89560)
## About The Pull Request
There are 3 radioactive reagents in the game with almost no effects
related to radiation.

Polonium causes irradiation but only when the reagent is inside the mob.
The rest do toxin damage, which seems silly to me. I've reworked these 3
reagents to now trigger a radiation pulse when exposed to an object or
mob. This radiation pulse only affects the target and does not apply to
surrounding areas. The chance of irradiation is determined by how
radioactive the reagent is which is now:
- Uranium (rad_power = 1) (max chance is 20 when TOUCH or VAPOR, max
chance is 1 when INGEST)
- Radium (rad_power = 2) (max chance is 35 when TOUCH or VAPOR, max
chance is 2 when INGEST)
- Polonium (rad_power = 3) (max chance is 50 when TOUCH or VAPOR, max
chance is 3 when INGEST)

The irradiation chance calculations follows a simple formula:
```
// if reagent is TOUCH or VAPOR the irradiate chance is
chance = reac_volume * rad_power

// if reagent is INGEST the irradiate chance is (per tick)
chance = volume / (20 - rad_power * 5)
```
This system is setup so that you can't just fill up a beaker or bottle
and toss it at someone and it guarantees they are irradiated. (that's
why there is a max chance restriction) Likewise I lowered the chance
significantly when the radioactive reagent is ingested so you can't just
slip 1u into someones drink and it guarantees irradiation.

## Why It's Good For The Game
Radioactive reagents were under utilized. The irradiation system also
sees very little action once the SM removed a lot of the old radiation
methods. This gives more interesting ways to cause chaos and deal long
term lasting damage besides brute/burn.

This can combo nicely with sabotaging a shower used for radiation
treatment by filling it with... radium. Also for my weather PR,
radioactive rain is cool as fuck and should irradiate things it touches
otherwise it ends up being purely cosmetic.

## Changelog
🆑
add: Add irradiation to radioactive reagents uranium, radium, and
polonium.
balance: Radioactive reagents uranium, radium, and polonium now cause
irradiate effects when they come into contact with mobs or objects. This
can be via several means, ingestion, touch, or vapors. The more
radioactive the reagent, the more likely it is to irradiate. Polonium is
the most radioactive with a x3 multiplier, radium is next with a x2
multiplier, and uranium is the weakest with just a x1 multiplier.
balance: Polonium no longer guarantees instant irradiation when the
reagent is inside a mob.
/🆑
2025-03-12 16:45:30 -04:00

82 lines
3.8 KiB
Plaintext

/// Whether or not it's possible for this atom to be irradiated
#define CAN_IRRADIATE(atom) (ishuman(##atom) || isitem(##atom))
/// Calculates the max chance for a radiation_pulse via a radioactive reagent
#define CALCULATE_RAD_MAX_CHANCE(rad_power) (20 + (15 * (rad_power - 1)))
/// Sends out a pulse of radiation, eminating from the source.
/// Radiation is performed by collecting all radiatables within the max range (0 means source only, 1 means adjacent, etc),
/// then makes their way towards them. A number, starting at 1, is multiplied
/// by the insulation amounts of whatever is in the way (for example, walls lowering it down).
/// If this number hits equal or below the threshold, then the target can no longer be irradiated.
/// If the number is above the threshold, then the chance is the chance that the target will be irradiated.
/// As a consumer, this means that max_range going up usually means you want to lower the threshold too,
/// as well as the other way around.
/// If max_range is high, but threshold is too high, then it usually won't reach the source at the max range in time.
/// If max_range is low, but threshold is too low, then it basically guarantees everyone nearby, even if there's walls
/// and such in the way, can be irradiated.
/// You can also pass in a minimum exposure time. If this is set, then this radiation pulse
/// will not irradiate the source unless they have been around *any* radioactive source for that
/// period of time.
/// The chance to get irradiated diminishes over range, and from objects that block radiation.
/// Assuming there is nothing in the way, the chance will determine what the chance is to get irradiated from half of max_range.
/// Example: If chance is equal to 30%, and max_range is equal to 8,
/// then the chance for a thing to get irradiated is 30% if they are 4 turfs away from the pulse source.
/proc/radiation_pulse(
atom/source,
max_range,
threshold,
chance = DEFAULT_RADIATION_CHANCE,
minimum_exposure_time = 0,
)
if(!SSradiation.can_fire)
return
var/datum/radiation_pulse_information/pulse_information = new
pulse_information.source_ref = WEAKREF(source)
pulse_information.max_range = max_range
pulse_information.threshold = threshold
pulse_information.chance = chance
pulse_information.minimum_exposure_time = minimum_exposure_time
pulse_information.turfs_to_process = RANGE_TURFS(max_range, source)
SSradiation.processing += pulse_information
return TRUE
/datum/radiation_pulse_information
var/datum/weakref/source_ref
var/max_range
var/threshold
var/chance
var/minimum_exposure_time
var/list/turfs_to_process
#define MEDIUM_RADIATION_THRESHOLD_RANGE 0.5
#define EXTREME_RADIATION_CHANCE 30
/// Gets the perceived "danger" of radiation pulse, given the threshold to the target.
/// Returns a RADIATION_DANGER_* define, see [code/__DEFINES/radiation.dm]
/proc/get_perceived_radiation_danger(datum/radiation_pulse_information/pulse_information, insulation_to_target)
if (insulation_to_target > pulse_information.threshold)
// We could get irradiated! The only thing stopping us now is chance, so scale based on that.
if (pulse_information.chance >= EXTREME_RADIATION_CHANCE)
return PERCEIVED_RADIATION_DANGER_EXTREME
else
return PERCEIVED_RADIATION_DANGER_HIGH
else
// We're out of the threshold from being irradiated, but by how much?
if (insulation_to_target / pulse_information.threshold <= MEDIUM_RADIATION_THRESHOLD_RANGE)
return PERCEIVED_RADIATION_DANGER_MEDIUM
else
return PERCEIVED_RADIATION_DANGER_LOW
/// A common proc used to send COMSIG_ATOM_PROPAGATE_RAD_PULSE to adjacent atoms
/// Only used for uranium (false/tram)walls to spread their radiation pulses
/atom/proc/propagate_radiation_pulse()
for(var/atom/atom in orange(1,src))
SEND_SIGNAL(atom, COMSIG_ATOM_PROPAGATE_RAD_PULSE, src)
#undef MEDIUM_RADIATION_THRESHOLD_RANGE
#undef EXTREME_RADIATION_CHANCE