-
-
Notifications
You must be signed in to change notification settings - Fork 452
/
pierce.dm
207 lines (175 loc) · 9.7 KB
/
pierce.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
Piercing wounds
*/
/datum/wound/pierce
name = "Piercing Wound"
sound_effect = 'sound/weapons/slice.ogg'
processes = TRUE
wound_type = WOUND_PIERCE
treatable_by = list(/obj/item/stack/medical/suture)
treatable_tool = TOOL_CAUTERY
base_treat_time = 3 SECONDS
wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE)
/// How much blood we start losing when this wound is first applied
var/initial_flow
/// If gauzed, what percent of the internal bleeding actually clots of the total absorption rate
var/gauzed_clot_rate
/// When hit on this bodypart, we have this chance of losing some blood + the incoming damage
var/internal_bleeding_chance
/// If we let off blood when hit, the max blood lost is this * the incoming damage
var/internal_bleeding_coefficient
/datum/wound/pierce/wound_injury(datum/wound/old_wound = null, attack_direction = null)
blood_flow = initial_flow
if(attack_direction && victim.blood_volume > BLOOD_VOLUME_OKAY(victim))
victim.spray_blood(attack_direction, severity)
/datum/wound/pierce/receive_damage(wounding_type, wounding_dmg, wound_bonus)
if(victim.stat == DEAD || wounding_dmg < 5)
return
if(victim.blood_volume && prob(internal_bleeding_chance + wounding_dmg))
if(limb.current_gauze && limb.current_gauze.splint_factor)
wounding_dmg *= (1 - limb.current_gauze.splint_factor)
var/blood_bled = rand(1, wounding_dmg * internal_bleeding_coefficient) // 12 brute toolbox can cause up to 15/18/21 bloodloss on mod/sev/crit
switch(blood_bled)
if(1 to 6)
victim.bleed(blood_bled, TRUE)
if(7 to 13)
victim.visible_message(span_smalldanger("Blood droplets fly from the hole in [victim]'s [limb.name]."), span_danger("You cough up a bit of blood from the blow to your [limb.name]."), vision_distance=COMBAT_MESSAGE_RANGE)
victim.bleed(blood_bled, TRUE)
if(14 to 19)
victim.visible_message(span_smalldanger("A small stream of blood spurts from the hole in [victim]'s [limb.name]!"), span_danger("You spit out a string of blood from the blow to your [limb.name]!"), vision_distance=COMBAT_MESSAGE_RANGE)
new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
victim.bleed(blood_bled)
if(20 to INFINITY)
victim.visible_message(span_danger("A spray of blood streams from the gash in [victim]'s [limb.name]!"), span_danger("<b>You choke up on a spray of blood from the blow to your [limb.name]!</b>"), vision_distance=COMBAT_MESSAGE_RANGE)
victim.bleed(blood_bled)
new /obj/effect/temp_visual/dir_setting/bloodsplatter(victim.loc, victim.dir)
victim.add_splatter_floor(get_step(victim.loc, victim.dir))
/datum/wound/pierce/get_bleed_rate_of_change()
if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS) || HAS_TRAIT(victim, TRAIT_BLOODY_MESS_LITE))
return BLOOD_FLOW_INCREASING
if(limb.current_gauze)
return BLOOD_FLOW_DECREASING
return BLOOD_FLOW_STEADY
/datum/wound/pierce/handle_process()
blood_flow = min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW)
if(victim.bodytemperature < (BODYTEMP_NORMAL - 10))
blood_flow -= 0.2
if(prob(5))
to_chat(victim, span_notice("You feel the [lowertext(name)] in your [limb.name] firming up from the cold!"))
if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS) && (victim.stat != DEAD))
blood_flow += 0.5 // old heparin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first
if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS_LITE) && (victim.stat != DEAD)) //hemophiliac version, half strength
blood_flow += 0.25
if(limb.current_gauze)
blood_flow -= limb.current_gauze.absorption_rate * gauzed_clot_rate
limb.current_gauze.absorption_capacity -= limb.current_gauze.absorption_rate
if(blood_flow <= 0)
qdel(src)
/datum/wound/pierce/on_stasis()
. = ..()
if(blood_flow <= 0)
qdel(src)
/datum/wound/pierce/check_grab_treatments(obj/item/I, mob/user)
if(I.get_temperature()) // if we're using something hot but not a cautery, we need to be aggro grabbing them first, so we don't try treating someone we're eswording
return TRUE
/datum/wound/pierce/treat(obj/item/I, mob/user)
if(istype(I, /obj/item/stack/medical/suture))
suture(I, user)
else if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature() > 300)
tool_cauterize(I, user)
/datum/wound/pierce/on_xadone(power)
. = ..()
blood_flow -= 0.03 * power // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort
/datum/wound/pierce/on_healium(power)
. = ..()
blood_flow -= 0.08 * power
/datum/wound/pierce/on_synthflesh(power)
. = ..()
blood_flow -= 0.05 * power // 20u * 0.05 = -1 blood flow, less than with slashes but still good considering smaller bleed rates
/// If someone is using a suture to close this puncture
/datum/wound/pierce/proc/suture(obj/item/stack/medical/suture/I, mob/user)
var/self_penalty_mult = (user == victim ? 1.4 : 1)
if(LAZYLEN(user.mind?.antag_datums) && severity > WOUND_SEVERITY_MODERATE) //antagonists can heal wounds better with ghetto alternatives, since they don't have as much access to proper medical treatment
self_penalty_mult = 1
user.visible_message(span_notice("[user] begins stitching [victim]'s [limb.name] with [I]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]..."))
playsound(I, pick(I.apply_sounds), 25)
if(!do_after(user, base_treat_time * self_penalty_mult * I.treatment_speed, victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
return
user.visible_message(span_green("[user] stitches up some of the bleeding on [victim]."), span_green("You stitch up some of the bleeding on [user == victim ? "yourself" : "[victim]"]."))
var/blood_sutured = I.stop_bleeding / self_penalty_mult
blood_flow -= blood_sutured
limb.heal_damage(I.heal_brute, I.heal_burn)
I.use(1)
if(blood_flow > 0)
try_treating(I, user)
else
to_chat(user, span_green("You successfully close the hole in [user == victim ? "your" : "[victim]'s"] [limb.name]."))
/// If someone is using either a cautery tool or something with heat to cauterize this pierce
/datum/wound/pierce/proc/tool_cauterize(obj/item/I, mob/user)
var/improv_penalty_mult = (I.tool_behaviour == TOOL_CAUTERY ? 1 : 1.25) // 25% longer and less effective if you don't use a real cautery
var/self_penalty_mult = (user == victim ? 1.5 : 1) // 50% longer and less effective if you do it to yourself
if(LAZYLEN(user.mind?.antag_datums) && severity > WOUND_SEVERITY_MODERATE)
improv_penalty_mult = 1
self_penalty_mult = 0.5
user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.name] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.name] with [I]..."))
playsound(I, 'sound/surgery/cautery1.ogg', 75, TRUE, falloff_exponent = 1)
if(!do_after(user, base_treat_time * self_penalty_mult * improv_penalty_mult * I.toolspeed, victim, extra_checks = CALLBACK(src, PROC_REF(still_exists))))
return
playsound(I, 'sound/surgery/cautery2.ogg', 75, TRUE, falloff_exponent = 1)
user.visible_message(span_green("[user] cauterizes some of the bleeding on [victim]."), span_green("You cauterize some of the bleeding on [victim]."))
limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND)
if(prob(30))
victim.emote("scream")
var/blood_cauterized = (0.6 / (self_penalty_mult * improv_penalty_mult))
blood_flow -= blood_cauterized
if(blood_flow > 0)
try_treating(I, user)
/datum/wound/pierce/moderate
name = "Minor Breakage"
desc = "Patient's skin has been broken open, causing severe bruising and minor internal bleeding in affected area."
treat_text = "Treat affected site with bandaging or exposure to extreme cold. In dire cases, brief exposure to vacuum may suffice." // space is cold in ss13, so it's like an ice pack!
examine_desc = "has a small, circular hole, gently bleeding"
occur_text = "spurts out a thin stream of blood"
sound_effect = 'sound/effects/wounds/pierce1.ogg'
severity = WOUND_SEVERITY_MODERATE
initial_flow = 1.5
gauzed_clot_rate = 0.8
internal_bleeding_chance = 30
internal_bleeding_coefficient = 1.25
threshold_minimum = 30
threshold_penalty = 2
status_effect_type = /datum/status_effect/wound/pierce/moderate
scar_keyword = "piercemoderate"
/datum/wound/pierce/severe
name = "Open Puncture"
desc = "Patient's internal tissue is penetrated, causing sizeable internal bleeding and reduced limb stability."
treat_text = "Repair punctures in skin by suture or cautery, extreme cold may also work."
examine_desc = "is pierced clear through, with bits of tissue obscuring the open hole"
occur_text = "looses a violent spray of blood, revealing a pierced wound"
sound_effect = 'sound/effects/wounds/pierce2.ogg'
severity = WOUND_SEVERITY_SEVERE
initial_flow = 2.25
gauzed_clot_rate = 0.6
internal_bleeding_chance = 60
internal_bleeding_coefficient = 1.5
threshold_minimum = 50
threshold_penalty = 35
status_effect_type = /datum/status_effect/wound/pierce/severe
scar_keyword = "piercesevere"
/datum/wound/pierce/critical
name = "Ruptured Cavity"
desc = "Patient's internal tissue and circulatory system is shredded, causing significant internal bleeding and damage to internal organs."
treat_text = "Surgical repair of puncture wound, followed by supervised blood infusion."
examine_desc = "is ripped clear through, barely held together by exposed bone"
occur_text = "blasts apart, sending chunks of viscera flying in all directions"
sound_effect = 'sound/effects/wounds/pierce3.ogg'
severity = WOUND_SEVERITY_CRITICAL
initial_flow = 3
gauzed_clot_rate = 0.4
internal_bleeding_chance = 80
internal_bleeding_coefficient = 1.75
threshold_minimum = 100
threshold_penalty = 50
status_effect_type = /datum/status_effect/wound/pierce/critical
scar_keyword = "piercecritical"
wound_flags = (FLESH_WOUND | ACCEPTS_GAUZE | MANGLES_FLESH)