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

Port updates to the regenerator component #4204

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
90 changes: 66 additions & 24 deletions code/datums/components/regenerator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,42 @@
/datum/component/regenerator
/// You will only regain health if you haven't been hurt for this many seconds
var/regeneration_delay
/// Health to regenerate per second
var/health_per_second
/// Brute reagined every second
var/brute_per_second
/// Burn reagined every second
var/burn_per_second
/// Toxin reagined every second
var/tox_per_second
/// Oxygen reagined every second
var/oxy_per_second
/// If TRUE, we'll try to heal wounds as well. Useless for non-humans.
var/heals_wounds = FALSE
/// List of damage types we don't care about, in case you want to only remove this with fire damage or something
var/list/ignore_damage_types
/// Colour of regeneration animation, or none if you don't want one
var/outline_colour
/// When this timer completes we start restoring health, it is a timer rather than a cooldown so we can do something on its completion
var/regeneration_start_timer

/datum/component/regenerator/Initialize(regeneration_delay = 6 SECONDS, health_per_second = 2, ignore_damage_types = list(STAMINA), outline_colour = COLOR_PALE_GREEN)
/datum/component/regenerator/Initialize(
regeneration_delay = 6 SECONDS,
brute_per_second = 2,
burn_per_second = 0,
tox_per_second = 0,
oxy_per_second = 0,
heals_wounds = FALSE,
ignore_damage_types = list(STAMINA),
outline_colour = COLOR_PALE_GREEN,
)
if (!isliving(parent))
return COMPONENT_INCOMPATIBLE

src.regeneration_delay = regeneration_delay
src.health_per_second = health_per_second
src.brute_per_second = brute_per_second
src.burn_per_second = burn_per_second
src.tox_per_second = tox_per_second
src.oxy_per_second = oxy_per_second
src.heals_wounds = heals_wounds
src.ignore_damage_types = ignore_damage_types
src.outline_colour = outline_colour

Expand All @@ -48,24 +69,20 @@
/datum/component/regenerator/proc/on_take_damage(datum/source, damage, damagetype, ...)
SIGNAL_HANDLER

if (damage <= 0)
return
if (locate(damagetype) in ignore_damage_types)
if (damagetype in ignore_damage_types)
return
stop_regenerating()
if(regeneration_start_timer)
deltimer(regeneration_start_timer)
regeneration_start_timer = addtimer(CALLBACK(src, PROC_REF(start_regenerating)), regeneration_delay, TIMER_STOPPABLE)
regeneration_start_timer = addtimer(CALLBACK(src, PROC_REF(start_regenerating)), regeneration_delay, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE)

/// Start processing health regeneration, and show animation if provided
/datum/component/regenerator/proc/start_regenerating()
. = TRUE
if (!should_be_regenning(parent))
return FALSE
var/mob/living/living_parent = parent
if (living_parent.stat == DEAD)
return
if (living_parent.health == living_parent.maxHealth)
return
living_parent.visible_message(span_notice("[living_parent]'s wounds begin to knit closed!"))
START_PROCESSING(SSobj, src)
regeneration_start_timer = null
if (!outline_colour)
return
living_parent.add_filter(REGENERATION_FILTER, 2, list("type" = "outline", "color" = outline_colour, "alpha" = 0, "size" = 1))
Expand All @@ -81,19 +98,44 @@
living_parent.remove_filter(REGENERATION_FILTER)

/datum/component/regenerator/process(seconds_per_tick = SSMOBS_DT)
var/mob/living/living_parent = parent
if (living_parent.stat == DEAD)
if (!should_be_regenning(parent))
stop_regenerating()
return
if (living_parent.health == living_parent.maxHealth)
stop_regenerating()
return
do_heal(health_per_second * seconds_per_tick) // monkestation edit: minor refactor

// monkestation start: minor refactor
/datum/component/regenerator/proc/do_heal(amt)
var/mob/living/living_parent = parent
living_parent.heal_overall_damage(amt)
// monkestation end
// Heal bonus for being in crit. Only applies to carbons
var/heal_mod = HAS_TRAIT(living_parent, TRAIT_CRITICAL_CONDITION) ? 2 : 1

var/need_mob_update = FALSE
if(brute_per_second)
need_mob_update += living_parent.adjustBruteLoss(-1 * heal_mod * brute_per_second * seconds_per_tick, updating_health = FALSE)
if(burn_per_second)
need_mob_update += living_parent.adjustFireLoss(-1 * heal_mod * burn_per_second * seconds_per_tick, updating_health = FALSE)
if(tox_per_second)
need_mob_update += living_parent.adjustToxLoss(-1 * heal_mod * tox_per_second * seconds_per_tick, updating_health = FALSE)
if(oxy_per_second)
need_mob_update += living_parent.adjustOxyLoss(-1 * heal_mod * oxy_per_second * seconds_per_tick, updating_health = FALSE)

if(heals_wounds && iscarbon(parent))
var/mob/living/carbon/carbon_parent = living_parent
for(var/datum/wound/iter_wound as anything in carbon_parent.all_wounds)
if(SPT_PROB(2 - (iter_wound.severity / 2), seconds_per_tick))
iter_wound.remove_wound()
need_mob_update++

if(need_mob_update)
living_parent.updatehealth()

/// Checks if the passed mob is in a valid state to be regenerating
/datum/component/regenerator/proc/should_be_regenning(mob/living/who)
if(who.stat == DEAD)
return FALSE
if(heals_wounds && iscarbon(who))
var/mob/living/carbon/carbon_who = who
if(length(carbon_who.all_wounds) > 0)
return TRUE
if(who.health != who.maxHealth)
return TRUE
return FALSE

#undef REGENERATION_FILTER
2 changes: 1 addition & 1 deletion code/modules/mob/living/basic/space_fauna/bear/_bear.dm
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@

AddComponent(/datum/component/regenerator,\
regeneration_delay = 1 SECONDS,\
health_per_second = 5,\
brute_per_second = 5,\
outline_colour = COLOR_YELLOW,\
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
AddComponent(\
/datum/component/regenerator,\
regeneration_delay = 4 SECONDS,\
health_per_second = maxHealth / 6,\
brute_per_second = maxHealth / 6,\
outline_colour = COLOR_PINK,\
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,19 @@
/obj/item/organ/internal/liver/teratoma
name = "horribly malformed liver"
desc = "It seems to pulse as if existed out of spite of nature itself."
var/datum/component/regenerator/teratoma/oh_god_why
var/datum/component/regenerator/oh_god_why

/obj/item/organ/internal/liver/teratoma/on_insert(mob/living/carbon/organ_owner, special)
. = ..()
oh_god_why = organ_owner.AddComponent(/datum/component/regenerator/teratoma, health_per_second = 1, ignore_damage_types = list(OXY, STAMINA), outline_colour = COLOR_RED_LIGHT) // ignore oxy damage so they can regen while in crit if you just leave them there
oh_god_why = organ_owner.AddComponent(\
/datum/component/regenerator,\
brute_per_second = 2,\
burn_per_second = 2,\
tox_per_second = 1,\
heals_wounds = TRUE,\
ignore_damage_types = list(OXY, STAMINA),\
outline_colour = COLOR_RED_LIGHT\
) // ignore oxy damage so they can regen while in crit if you just leave them there
RegisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(prevent_banned_reagent_exposure))
if(ishuman(organ_owner))
var/mob/living/carbon/human/human_owner = organ_owner
Expand Down Expand Up @@ -137,8 +145,3 @@
incidents_left = INFINITY
luck_mod = 0.75
damage_mod = 0.2

/datum/component/regenerator/teratoma/do_heal(amt)
var/mob/living/living_parent = parent
living_parent.heal_overall_damage(brute = amt, burn = amt, updating_health = FALSE)
living_parent.adjustToxLoss(-(amt * 0.5), updating_health = TRUE)
Loading