Files
RikuTheKillerandGitHub 7fe431dee2 Make blood worms take damage from pressure instead of lack of oxygen and tweak their environmental damage values (#96607)
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request

Extension to #96385

I added `/datum/element/pressure_sensitive` for making mobs sensitive to
low/high pressure limits, then implemented it for blood worms so they
take damage from low pressure. The element also has the same
`/proc/check_safe_environment` setup that
`/datum/element/body_temp_sensitive` has, for future-proofing in case
pressure sensitivity is expanded to all basic mobs.

I also did some message fixes for the pressure and temperature alerts.
The temperature alert no longer breaks if the damage being dealt is
below 1 but above 0. Also, the check for more severe alerts is now
effectively `>=` instead of `>`, meaning that 5 damage is now considered
high severity.

Hatchlings take 0.5 DPS from low pressure and 0.5 DPS from cold
temperatures. All blood worms have low absolute values for minimum
pressure and minimum temperature, but they're still reliably screwed
over by space which is what I want.

Lastly, I made blood worms breathless again.

EDIT: I also updated the antag info panel to match #95920.

<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->

## Why It's Good For The Game

Blood worm hatchlings are highly dependent on vents for being able to
play the game. I don't want distro losing pressure or an atmos tech
optimizing distro density with low temperature to be a gotcha for blood
worms. Those happen coincidentally pretty often with no intention to
kill blood worms behind them and losing to something like that right
after you spawn just feels bad.

The pressure and cold damage in general is meant to prevent blood worms
from spacewalking and breaking every window in sight to expand their
effective domain. They can still get hosts with space suits to
circumvent this.

<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->

## Changelog

<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and its effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->

🆑
fix: Low temperature alerts now appear for basic mobs when the damage
being dealt is below 1 but above 0 (e.g. 0.5 DPS).
balance: Blood worms are now breathless again.
balance: Blood worms take damage from low pressures now (increases with
growth stage).
/🆑

<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
2026-07-05 17:38:28 -07:00

86 lines
3.3 KiB
Plaintext

/// When attached to a living mob, causes it to take damage over time when pressure is too low or too high as defined by the element's arguments.
/datum/element/pressure_sensitive
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
argument_hash_end_idx = 5
/// The pressure (in kilopascals) below which low_pressure_damage is taken.
var/min_pressure = WARNING_LOW_PRESSURE
/// The pressure (in kilopascals) above which high_pressure_damage is taken.
var/max_pressure = HAZARD_HIGH_PRESSURE
/// The damage taken when pressure is below min_pressure. 0 or below disables low pressure damage.
var/low_pressure_damage = 1
/// The damage taken when pressure is above max_pressure. 0 or below disables high pressure damage.
var/high_pressure_damage = 1
/datum/element/pressure_sensitive/Attach(datum/target, min_pressure, max_pressure, low_pressure_damage, high_pressure_damage, mapload = FALSE)
. = ..()
if (!isliving(target))
return ELEMENT_INCOMPATIBLE
if (isnum(min_pressure))
src.min_pressure = min_pressure
if (isnum(max_pressure))
src.max_pressure = max_pressure
if (isnum(low_pressure_damage))
src.low_pressure_damage = low_pressure_damage
if (isnum(high_pressure_damage))
src.high_pressure_damage = high_pressure_damage
RegisterSignal(target, COMSIG_LIVING_LIFE, PROC_REF(on_life))
if(mapload && PERFORM_ALL_TESTS(focus_only/atmos_and_temp_requirements))
check_safe_environment(target)
/datum/element/pressure_sensitive/Detach(datum/target)
if(target)
UnregisterSignal(target, COMSIG_LIVING_LIFE)
return ..()
/datum/element/pressure_sensitive/proc/on_life(mob/living/target, seconds_per_tick)
SIGNAL_HANDLER
if (HAS_TRAIT(target, TRAIT_STASIS))
return
var/gave_alert = FALSE
var/datum/gas_mixture/environment = target.loc.return_air()
var/pressure = target.calculate_affecting_pressure(environment.return_pressure())
if(pressure < min_pressure && low_pressure_damage > 0 && !HAS_TRAIT(target, TRAIT_RESISTLOWPRESSURE))
target.adjust_brute_loss(low_pressure_damage * seconds_per_tick)
switch(low_pressure_damage)
if(5 to INFINITY)
target.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/lowpressure, 2)
if(-INFINITY to 5)
target.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/lowpressure, 1)
gave_alert = TRUE
else if(pressure > max_pressure && high_pressure_damage > 0 && !HAS_TRAIT(target, TRAIT_RESISTHIGHPRESSURE))
target.adjust_brute_loss(high_pressure_damage * seconds_per_tick)
switch(high_pressure_damage)
if(5 to INFINITY)
target.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/highpressure, 2)
if(-INFINITY to 5)
target.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/highpressure, 1)
gave_alert = TRUE
if(!gave_alert)
target.clear_alert(ALERT_PRESSURE)
/// Ensures that the given mob is in a safe environment.
/datum/element/pressure_sensitive/proc/check_safe_environment(mob/living/target)
if(target.stat == DEAD || isnull(target.loc))
return
var/atom/loc = target.loc
var/datum/gas_mixture/environment = loc.return_air()
var/pressure = target.calculate_affecting_pressure(environment.return_pressure())
if(!ISINRANGE(pressure, min_pressure, max_pressure))
stack_trace("[target] loaded on in a loc with unsafe pressure at \[[loc.x], [loc.y], [loc.z]\] (area : [get_area(loc)]): [pressure]kPa. Acceptable Range: [min_pressure]kPa - [max_pressure]kPa,")