Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Moves simplemob atmos and temperature requirements to DCS elements. #25619

Merged
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions code/__DEFINES/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,10 @@
#define COMSIG_LIVING_WRITE_MEMORY "living_write_memory"
#define COMPONENT_DONT_WRITE_MEMORY (1<<0)

// /mob/living/simple_animal signals
///from /mob/living/simple_animal/handle_environment()
#define COMSIG_SIMPLEANIMAL_HANDLE_ENVIRONMENT "simpleanimal_handle_environment"

// /mob/living/carbon signals

///from base of mob/living/carbon/soundbang_act(): (list(intensity))
Expand Down
73 changes: 73 additions & 0 deletions code/datums/elements/atmos_requirements.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Bespoke element that deals damage to the attached mob when the atmos requirements aren't satisfied
*/
/datum/element/atmos_requirements
element_flags = ELEMENT_BESPOKE
id_arg_index = 2

Check failure on line 6 in code/datums/elements/atmos_requirements.dm

View workflow job for this annotation

GitHub Actions / Run Linters

undefined var 'id_arg_index' on type '/datum/element/atmos_requirements'
/// An assoc list of "what atmos does this mob require to survive in".
var/list/atmos_requirements
/// How much (brute) damage we take from being in unsuitable atmos.
var/unsuitable_atmos_damage

/datum/element/atmos_requirements/Attach(datum/target, list/atmos_requirements_, unsuitable_atmos_damage_ = 5)
. = ..()

if(!issimple_animal(target))
return ELEMENT_INCOMPATIBLE

if(!atmos_requirements_)
stack_trace("[type] added to [target] without any requirements specified.")

atmos_requirements = atmos_requirements_
unsuitable_atmos_damage = unsuitable_atmos_damage_
RegisterSignal(target, COMSIG_SIMPLEANIMAL_HANDLE_ENVIRONMENT, PROC_REF(handle_environment))

/datum/element/atmos_requirements/Detach(datum/target)
UnregisterSignal(target, COMSIG_SIMPLEANIMAL_HANDLE_ENVIRONMENT)
return ..()

/datum/element/atmos_requirements/proc/handle_environment(mob/living/simple_animal/target, datum/gas_mixture/readonly_environment)
SIGNAL_HANDLER // COMSIG_SIMPLEANIMAL_HANDLE_ENVIRONMENT

if(!readonly_environment)
return

var/atmos_suitable = TRUE

var/tox = readonly_environment.toxins()
var/oxy = readonly_environment.oxygen()
var/n2 = readonly_environment.nitrogen()
var/co2 = readonly_environment.carbon_dioxide()

if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
atmos_suitable = FALSE
target.throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy)
else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"])
atmos_suitable = FALSE
target.throw_alert("too_much_oxy", /atom/movable/screen/alert/too_much_oxy)
else
target.clear_alert("not_enough_oxy")
target.clear_alert("too_much_oxy")

if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"])
atmos_suitable = FALSE
target.throw_alert("not_enough_tox", /atom/movable/screen/alert/not_enough_tox)
else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"])
atmos_suitable = FALSE
target.throw_alert("too_much_tox", /atom/movable/screen/alert/too_much_tox)
else
target.clear_alert("too_much_tox")
target.clear_alert("not_enough_tox")

if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"])
atmos_suitable = FALSE
else if(atmos_requirements["max_n2"] && n2 > atmos_requirements["max_n2"])
atmos_suitable = FALSE

if(atmos_requirements["min_co2"] && co2 < atmos_requirements["min_co2"])
atmos_suitable = FALSE
else if(atmos_requirements["max_co2"] && co2 > atmos_requirements["max_co2"])
atmos_suitable = FALSE

if(!atmos_suitable)
target.adjustHealth(unsuitable_atmos_damage)
68 changes: 68 additions & 0 deletions code/datums/elements/body_temperature.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#define NONCARBON_DEFAULT_MIN_BODY_TEMP 250
#define NONCARBON_DEFAULT_MAX_BODY_TEMP 350
#define NONCARBON_DEFAULT_COLD_DAMAGE 2
#define NONCARBON_DEFAULT_HEAT_DAMAGE 2

/**
* Bespoke element that deals damage to the attached mob when the ambient temperature is unsuitable.
*/
/datum/element/body_temperature
element_flags = ELEMENT_BESPOKE
id_arg_index = 2

Check failure on line 11 in code/datums/elements/body_temperature.dm

View workflow job for this annotation

GitHub Actions / Run Linters

undefined var 'id_arg_index' on type '/datum/element/body_temperature'

/// Min body temp
var/min_body_temp = NONCARBON_DEFAULT_MIN_BODY_TEMP
/// Max body temp
var/max_body_temp = NONCARBON_DEFAULT_MAX_BODY_TEMP

//// Damage when below min temp
var/cold_damage_per_tick = NONCARBON_DEFAULT_COLD_DAMAGE
/// Damage when above max temp
var/heat_damage_per_tick = NONCARBON_DEFAULT_HEAT_DAMAGE

/datum/element/body_temperature/Attach(datum/target, min_body_temp_, max_body_temp_, cold_damage_per_tick_, heat_damage_per_tick_)
. = ..()

if(!issimple_animal(target))
return ELEMENT_INCOMPATIBLE

if(isnum(min_body_temp))
min_body_temp = min_body_temp_

if(isnum(max_body_temp))
max_body_temp = max_body_temp_

if(isnum(cold_damage_per_tick))
cold_damage_per_tick = cold_damage_per_tick_

if(isnum(heat_damage_per_tick))
heat_damage_per_tick = heat_damage_per_tick_

RegisterSignal(target, COMSIG_SIMPLEANIMAL_HANDLE_ENVIRONMENT, PROC_REF(handle_temperature))

/datum/element/body_temperature/Detach(datum/target)
UnregisterSignal(target, COMSIG_SIMPLEANIMAL_HANDLE_ENVIRONMENT)
return ..()

/datum/element/body_temperature/proc/handle_temperature(mob/living/simple_animal/target, datum/gas_mixture/readonly_environment)
SIGNAL_HANDLER // COMSIG_SIMPLEANIMAL_HANDLE_ENVIRONMENT

if(!readonly_environment)
return

var/areatemp = target.get_temperature(readonly_environment)

if(abs(areatemp - target.bodytemperature) > 5 && !HAS_TRAIT(src, TRAIT_NOBREATH))
var/diff = areatemp - target.bodytemperature
diff = diff / 5
target.bodytemperature += diff

if(target.bodytemperature < min_body_temp)
target.adjustHealth(cold_damage_per_tick)
else if(target.bodytemperature > max_body_temp)
target.adjustHealth(heat_damage_per_tick)

#undef NONCARBON_DEFAULT_MIN_BODY_TEMP
#undef NONCARBON_DEFAULT_MAX_BODY_TEMP
#undef NONCARBON_DEFAULT_COLD_DAMAGE
#undef NONCARBON_DEFAULT_HEAT_DAMAGE
3 changes: 2 additions & 1 deletion code/modules/mob/living/living_life.dm
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@
/mob/living/proc/handle_random_events()
return

/mob/living/proc/handle_environment(datum/gas_mixture/environment)
/// Handle temperature/pressure differences between body and environment
/mob/living/proc/handle_environment()
return

/mob/living/proc/update_pulling()
Expand Down
76 changes: 19 additions & 57 deletions code/modules/mob/living/simple_animal/simple_animal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@
AddComponent(/datum/component/footstep, footstep_type)
add_strippable_element()

apply_atmos_requirements()
AddElement(/datum/element/body_temperature, minbodytemp, maxbodytemp, cold_damage_per_tick, heat_damage_per_tick)

/mob/living/simple_animal/Destroy()
/// We need to clear the reference to where we're walking to properly GC
walk_to(src, 0)
Expand All @@ -181,8 +184,23 @@
if(T && AIStatus == AI_Z_OFF)
SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src

remove_atmos_requirements()
RemoveElement(/datum/element/body_temperature)

return ..()

/mob/living/simple_animal/proc/apply_atmos_requirements()
if(unsuitable_atmos_damage == 0)
return

// String assoc list returns a cached list, so this is like a static list to
// pass into the element below.
Burzah marked this conversation as resolved.
Show resolved Hide resolved
atmos_requirements = string_assoc_list(atmos_requirements)
AddElement(/datum/element/atmos_requirements, atmos_requirements, unsuitable_atmos_damage)

/mob/living/simple_animal/proc/remove_atmos_requirements()
RemoveElement(/datum/element/atmos_requirements)

/mob/living/simple_animal/handle_atom_del(atom/A)
if(A == pcollar)
pcollar = null
Expand Down Expand Up @@ -288,64 +306,8 @@
else
custom_emote(EMOTE_AUDIBLE, pick(emote_hear))


/mob/living/simple_animal/handle_environment(datum/gas_mixture/readonly_environment)
if(!readonly_environment)
return
var/atmos_suitable = 1

var/areatemp = get_temperature(readonly_environment)

if(abs(areatemp - bodytemperature) > 5 && !HAS_TRAIT(src, TRAIT_NOBREATH))
var/diff = areatemp - bodytemperature
diff = diff / 5
bodytemperature += diff

var/tox = readonly_environment.toxins()
var/oxy = readonly_environment.oxygen()
var/n2 = readonly_environment.nitrogen()
var/co2 = readonly_environment.carbon_dioxide()

if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
atmos_suitable = 0
throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy)
else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"])
atmos_suitable = 0
throw_alert("too_much_oxy", /atom/movable/screen/alert/too_much_oxy)
else
clear_alert("not_enough_oxy")
clear_alert("too_much_oxy")

if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"])
atmos_suitable = 0
throw_alert("not_enough_tox", /atom/movable/screen/alert/not_enough_tox)
else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"])
atmos_suitable = 0
throw_alert("too_much_tox", /atom/movable/screen/alert/too_much_tox)
else
clear_alert("too_much_tox")
clear_alert("not_enough_tox")

if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"])
atmos_suitable = 0
else if(atmos_requirements["max_n2"] && n2 > atmos_requirements["max_n2"])
atmos_suitable = 0

if(atmos_requirements["min_co2"] && co2 < atmos_requirements["min_co2"])
atmos_suitable = 0
else if(atmos_requirements["max_co2"] && co2 > atmos_requirements["max_co2"])
atmos_suitable = 0

if(!atmos_suitable)
adjustHealth(unsuitable_atmos_damage)

handle_temperature_damage()

/mob/living/simple_animal/proc/handle_temperature_damage()
if(bodytemperature < minbodytemp)
adjustHealth(cold_damage_per_tick)
else if(bodytemperature > maxbodytemp)
adjustHealth(heat_damage_per_tick)
SEND_SIGNAL(src, COMSIG_SIMPLEANIMAL_HANDLE_ENVIRONMENT, readonly_environment)

/mob/living/simple_animal/gib()
if(icon_gib)
Expand Down
2 changes: 2 additions & 0 deletions paradise.dme
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,8 @@
#include "code\datums\diseases\advance\symptoms\weight.dm"
#include "code\datums\diseases\advance\symptoms\youth.dm"
#include "code\datums\elements\_element.dm"
#include "code\datums\elements\atmos_requirements.dm"
#include "code\datums\elements\body_temperature.dm"
#include "code\datums\elements\bombable_turf.dm"
#include "code\datums\elements\earhealing.dm"
#include "code\datums\elements\rad_insulation.dm"
Expand Down
Loading