-
-
Notifications
You must be signed in to change notification settings - Fork 452
/
regenerator.dm
93 lines (81 loc) · 3.43 KB
/
regenerator.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#define REGENERATION_FILTER "healing_glow"
/**
* # Regenerator component
*
* A mob with this component will regenerate its health over time, as long as it has not received damage
* in the last X seconds. Taking any damage will reset this cooldown.
*/
/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
/// 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)
if (!isliving(parent))
return COMPONENT_INCOMPATIBLE
src.regeneration_delay = regeneration_delay
src.health_per_second = health_per_second
src.ignore_damage_types = ignore_damage_types
src.outline_colour = outline_colour
/datum/component/regenerator/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_take_damage))
/datum/component/regenerator/UnregisterFromParent()
. = ..()
if(regeneration_start_timer)
deltimer(regeneration_start_timer)
UnregisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE)
stop_regenerating()
/datum/component/regenerator/Destroy(force, silent)
stop_regenerating()
. = ..()
if(regeneration_start_timer)
deltimer(regeneration_start_timer)
/// When you take damage, reset the cooldown and start processing
/datum/component/regenerator/proc/on_take_damage(datum/source, damage, damagetype)
SIGNAL_HANDLER
if (damage <= 0)
return
if (locate(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)
/// Start processing health regeneration, and show animation if provided
/datum/component/regenerator/proc/start_regenerating()
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)
if (!outline_colour)
return
living_parent.add_filter(REGENERATION_FILTER, 2, list("type" = "outline", "color" = outline_colour, "alpha" = 0, "size" = 1))
var/filter = living_parent.get_filter(REGENERATION_FILTER)
animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1)
animate(alpha = 0, time = 0.5 SECONDS)
/datum/component/regenerator/proc/stop_regenerating()
STOP_PROCESSING(SSobj, src)
var/mob/living/living_parent = parent
var/filter = living_parent.get_filter(REGENERATION_FILTER)
animate(filter)
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)
stop_regenerating()
return
if (living_parent.health == living_parent.maxHealth)
stop_regenerating()
return
living_parent.heal_overall_damage(health_per_second * seconds_per_tick)
#undef REGENERATION_FILTER