Skip to content

Commit 70dc242

Browse files
authored
Surgery changes and fixes (#1007)
* load of changes * runtimes * grabs share blood * another runtime * cmon man * blood spread stuff * fix get_item_covering_zone * fixes and qol * tweak * fixes blood spread * unused var * deencasement bloodies your body
1 parent d470e2a commit 70dc242

36 files changed

+580
-347
lines changed

code/__DEFINES/surgery.dm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,17 @@
77
#define SURGERY_NEEDS_RETRACTED (1<<4)
88
/// Bodypart needs a broken bone AND retracted incision or large cut
99
#define SURGERY_NEEDS_DEENCASEMENT (1<<5)
10+
/// Surgery step bloodies gloves when necessary.
11+
#define SURGERY_BLOODY_GLOVES (1<<6)
12+
/// Surgery step bloodies gloves + suit when necessary.
13+
#define SURGERY_BLOODY_BODY (1<<7)
14+
/// Surgery does not use RNG.
15+
#define SURGERY_CANNOT_FAIL (1<<8)
1016

1117
/// Only one of this type of implant may be in a target
1218
#define IMPLANT_HIGHLANDER (1<<0)
1319
/// Shows implant name in body scanner
1420
#define IMPLANT_KNOWN (1<<1)
1521
/// Hides the implant from the body scanner completely
1622
#define IMPLANT_HIDDEN (1<<2)
23+

code/__HELPERS/global_lists.dm

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@
6969
if(!isabstract(path))
7070
path = new path()
7171
GLOB.surgeries_list += path
72-
if(!length(path.allowed_tools))
73-
stack_trace("Surgery type [path.type] has no allowed_items list.")
7472

7573
sort_list(GLOB.surgeries_list, GLOBAL_PROC_REF(cmp_typepaths_asc))
7674

code/__HELPERS/mobs.dm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
return GET_BLOOD_REF(path)
2121

2222
/proc/get_blood_dna_color(list/blood_dna)
23-
var/datum/blood/blood_type = blood_dna[blood_dna[length(blood_dna)]]
24-
return blood_type.color
23+
var/datum/blood/blood_type = blood_dna?[blood_dna[length(blood_dna)]]
24+
return blood_type?.color
2525

2626
/proc/random_eye_color()
2727
switch(pick(20;"brown",20;"hazel",20;"grey",15;"blue",15;"green",1;"amber",1;"albino"))

code/__HELPERS/type2type.dm

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,28 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,
247247
if(ITEM_SLOT_LEGCUFFED)
248248
return pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
249249

250+
/proc/body_zone2item_slots(zone)
251+
switch(zone)
252+
if(BODY_ZONE_HEAD)
253+
return ITEM_SLOT_HEAD|ITEM_SLOT_MASK
254+
255+
if(BODY_ZONE_PRECISE_EYES)
256+
return ITEM_SLOT_EYES
257+
258+
if(BODY_ZONE_CHEST)
259+
return ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING
260+
261+
if(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM)
262+
return ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING|ITEM_SLOT_GLOVES
263+
264+
if(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND)
265+
return ITEM_SLOT_GLOVES
266+
267+
if(BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
268+
return ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING|ITEM_SLOT_FEET
269+
270+
if(BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT)
271+
return ITEM_SLOT_FEET
250272
//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
251273
/proc/heat2colour(temp)
252274
return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp))

code/_onclick/item_attack.dm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
/mob/living/attackby(obj/item/attacking_item, mob/living/user, params)
153153
if(..())
154154
return TRUE
155-
if (user.can_operate_on(src) && attacking_item.attempt_surgery(src, user))
155+
if (user.can_perform_surgery_on(src) && attacking_item.attempt_surgery(src, user))
156156
return TRUE
157157

158158
user.changeNext_move(attacking_item.combat_click_delay)

code/datums/components/bloodysoles.dm

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,17 @@
9999
if(HAS_TRAIT(parent_atom, TRAIT_LIGHT_STEP)) //the character is agile enough to don't mess their clothing and hands just from one blood splatter at floor
100100
return TRUE
101101

102-
parent_atom.add_blood_DNA(pool.return_blood_DNA())
102+
if(ishuman(parent_atom))
103+
var/bloody_slots = ITEM_SLOT_OCLOTHING|ITEM_SLOT_ICLOTHING|ITEM_SLOT_FEET
104+
var/mob/living/carbon/human/to_bloody = parent_atom
105+
if(to_bloody.body_position == LYING_DOWN)
106+
bloody_slots |= ITEM_SLOT_HEAD|ITEM_SLOT_MASK|ITEM_SLOT_GLOVES
107+
108+
to_bloody.add_blood_DNA_to_items(pool.return_blood_DNA(), bloody_slots)
109+
110+
else
111+
parent_atom.add_blood_DNA(pool.return_blood_DNA())
112+
103113
if(pool.bloodiness <= 0)
104114
qdel(pool)
105115

code/datums/forensics.dm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@
2121
parent = null
2222
return ..()
2323

24+
/// Adds blood dna. Returns TRUE if the blood dna list expanded.
2425
/datum/forensics/proc/add_blood_DNA(list/dna)
2526
if(!length(dna))
2627
return
27-
28+
var/old_len = length(blood_DNA)
2829
LAZYINITLIST(blood_DNA)
2930
for(var/dna_hash in dna)
3031
blood_DNA[dna_hash] = dna[dna_hash]
3132

3233
check_blood()
33-
return TRUE
34+
return old_len < length(blood_DNA)
3435

3536
/datum/forensics/proc/add_trace_DNA(list/dna)
3637
if(!length(dna))

code/game/objects/effects/decals/cleanable/humans.dm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@
8585
if(!is_dry)
8686
color = blood_color
8787

88+
/obj/effect/decal/cleanable/blood/attack_hand(mob/living/user, list/modifiers)
89+
. = ..()
90+
if(ishuman(user) && blood_DNA_length())
91+
var/mob/living/carbon/human/H = user
92+
H.add_blood_DNA_to_items(return_blood_DNA(), ITEM_SLOT_GLOVES)
93+
H.visible_message(span_notice("[user.name] runs [H.p_their()] fingers through [src]."))
94+
8895
/obj/effect/decal/cleanable/blood/proc/get_timer()
8996
drytime = world.time + dry_duration
9097

code/modules/clothing/gloves/_gloves.dm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
/obj/item/clothing/gloves/worn_overlays(mob/living/carbon/human/wearer, mutable_appearance/standing, isinhands = FALSE)
3232
. = ..()
33-
if(!isinhands)
33+
if(isinhands)
3434
return
3535

3636
if(damaged_clothes)

code/modules/codex/categories/surgery.dm

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,25 @@
6161
for(var/datum/surgery_step/step as anything in GLOB.surgeries_list)
6262
var/list/info = list("<ul>")
6363

64-
var/obj/path_or_tool = step.allowed_tools[1]
65-
info += "<li>Best performed with \a [istext(path_or_tool) ? "[path_or_tool]" : "[initial(path_or_tool.name)]"].</li>"
66-
if(!step.surgery_candidate_flags)
64+
var/obj/path_or_tool = step.allowed_tools?[1]
65+
if(path_or_tool)
66+
info += "<li>Best performed with \a [istext(path_or_tool) ? "[path_or_tool]" : "[initial(path_or_tool.name)]"].</li>"
67+
68+
if(!(step.surgery_flags & ~(SURGERY_CANNOT_FAIL | SURGERY_BLOODY_BODY | SURGERY_BLOODY_GLOVES)))
6769
info += "<li>This operation has no requirements."
6870
else
69-
if(step.surgery_candidate_flags & SURGERY_NO_FLESH)
71+
if(step.surgery_flags & SURGERY_NO_FLESH)
7072
info += "<li>This operation cannot be performed on organic limbs."
71-
else if(step.surgery_candidate_flags & SURGERY_NO_ROBOTIC)
73+
else if(step.surgery_flags & SURGERY_NO_ROBOTIC)
7274
info += "<li>This operation cannot be performed on robotic limbs."
7375

74-
if(step.surgery_candidate_flags & SURGERY_NO_STUMP)
76+
if(step.surgery_flags & SURGERY_NO_STUMP)
7577
info += "<li>This operation cannot be performed on stumps."
76-
if(step.surgery_candidate_flags & SURGERY_NEEDS_INCISION)
78+
if(step.surgery_flags & SURGERY_NEEDS_INCISION)
7779
info += "<li>This operation requires <b>[step.strict_access_requirement ? "exactly" : "atleast"]</b> an [CODEX_LINK("incision", "make incision")] or small cut.</li>"
78-
else if(step.surgery_candidate_flags & (SURGERY_NEEDS_RETRACTED|SURGERY_NEEDS_DEENCASEMENT))
80+
else if(step.surgery_flags & (SURGERY_NEEDS_RETRACTED|SURGERY_NEEDS_DEENCASEMENT))
7981
info += "<li>This operation requires <b>[step.strict_access_requirement ? "exactly" : "atleast"]</b> a [CODEX_LINK("widened incision", "widen incision")] or large cut.</li>"
80-
else if(step.surgery_candidate_flags & SURGERY_NEEDS_DEENCASEMENT)
82+
else if(step.surgery_flags & SURGERY_NEEDS_DEENCASEMENT)
8183
info += "<li>This operation requires the encasing bones to be [CODEX_LINK("broken", "saw through bone")].</li>"
8284

8385
info += "</ul>"

code/modules/detectivework/detective_work.dm

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,14 @@
4343
/// Adds the fibers of M to our fiber list.
4444
/atom/proc/add_fibers(mob/living/carbon/human/M)
4545
if(istype(M))
46-
var/old = 0
4746
if(M.gloves && istype(M.gloves, /obj/item/clothing))
4847
var/obj/item/clothing/gloves/G = M.gloves
49-
old = length(G.return_blood_DNA())
5048

51-
if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
52-
if(add_blood_DNA(G.return_blood_DNA()) && length(G.return_blood_DNA()) > old) //only reduces the bloodiness of our gloves if the item wasn't already bloody
53-
G.transfer_blood--
49+
if(G.transfer_blood > 1 && add_blood_DNA(G.return_blood_DNA())) //bloodied gloves transfer blood to touched objects
50+
G.transfer_blood--
5451

55-
else if(M.blood_in_hands > 1)
56-
old = length(M.return_blood_DNA())
57-
if(add_blood_DNA(M.return_blood_DNA()) && length(M.return_blood_DNA()) > old)
58-
M.blood_in_hands--
52+
else if(M.blood_in_hands > 1 && add_blood_DNA(M.return_blood_DNA()))
53+
M.blood_in_hands--
5954

6055
if(isnull(forensics))
6156
create_forensics()
@@ -99,6 +94,7 @@
9994

10095
forensics.add_trace_DNA(dna)
10196

97+
/// Returns TRUE if new blood dna was added.
10298
/atom/proc/add_blood_DNA(list/dna) //ASSOC LIST DNA = BLOODTYPE
10399
return FALSE
104100

@@ -109,8 +105,7 @@
109105
if(isnull(forensics))
110106
create_forensics()
111107

112-
forensics.add_blood_DNA(dna)
113-
return TRUE
108+
return forensics.add_blood_DNA(dna)
114109

115110
/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
116111
. = ..()
@@ -122,30 +117,55 @@
122117
B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
123118

124119
if(!QDELETED(B))
125-
B.add_blood_DNA(blood_dna) //give blood info to the blood decal.
126-
return TRUE //we bloodied the floor
120+
return B.add_blood_DNA(blood_dna) //give blood info to the blood decal.
127121

128122
/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
129-
if(wear_suit)
130-
wear_suit.add_blood_DNA(blood_dna)
131-
update_worn_oversuit()
123+
return add_blood_DNA_to_items(blood_dna)
124+
125+
/// Adds blood DNA to certain slots the mob is wearing
126+
/mob/living/carbon/human/proc/add_blood_DNA_to_items(
127+
list/blood_DNA_to_add,
128+
target_flags = ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING|ITEM_SLOT_GLOVES|ITEM_SLOT_HEAD|ITEM_SLOT_MASK,
129+
)
130+
if(QDELING(src))
131+
return FALSE
132+
133+
if(!length(blood_DNA_to_add))
134+
return FALSE
135+
136+
// Don't messy up our jumpsuit if we're got a coat
137+
if((obscured_slots & HIDEJUMPSUIT) || ((target_flags & ITEM_SLOT_OCLOTHING) && (wear_suit?.body_parts_covered & CHEST)))
138+
target_flags &= ~ITEM_SLOT_ICLOTHING
139+
140+
var/dirty_hands = !!(target_flags & (ITEM_SLOT_GLOVES|ITEM_SLOT_HANDS))
141+
var/dirty_feet = !!(target_flags & ITEM_SLOT_FEET)
142+
var/slots_to_bloody = target_flags & ~check_obscured_slots()
143+
var/list/all_worn = get_equipped_items()
132144

133-
else if(w_uniform)
134-
w_uniform.add_blood_DNA(blood_dna)
135-
update_worn_undersuit()
145+
for(var/obj/item/thing as anything in all_worn)
146+
if(thing.slot_flags & slots_to_bloody)
147+
thing.add_blood_DNA(blood_DNA_to_add)
136148

137-
if(gloves)
138-
var/obj/item/clothing/gloves/G = gloves
139-
G.add_blood_DNA(blood_dna)
149+
if(thing.body_parts_covered & HANDS)
150+
dirty_hands = FALSE
140151

141-
else if(length(blood_dna))
152+
if(thing.body_parts_covered & FEET)
153+
dirty_feet = FALSE
154+
155+
if(slots_to_bloody & ITEM_SLOT_HANDS)
156+
for(var/obj/item/thing in held_items)
157+
thing.add_blood_DNA(blood_DNA_to_add)
158+
159+
if(dirty_hands || dirty_feet || !length(all_worn))
142160
if(isnull(forensics))
143161
create_forensics()
144-
forensics.add_blood_DNA(blood_dna)
162+
forensics.add_blood_DNA(blood_DNA_to_add)
145163

146-
update_worn_gloves() //handles bloody hands overlays and updating
147-
return TRUE
164+
if(dirty_hands)
165+
blood_in_hands = max(blood_in_hands, rand(2, 4))
148166

167+
update_clothing(slots_to_bloody)
168+
return TRUE
149169
/*
150170
* Transfer all forensic evidence from [src] to [transfer_to].
151171
*/

code/modules/grab/grab_datum.dm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ GLOBAL_LIST_EMPTY(all_grabstates)
388388
return FALSE
389389

390390
if (assailant.incapacitated(IGNORE_GRAB))
391-
let_go(G)
391+
qdel(G)
392392
stack_trace("Someone resisted a grab while the assailant was incapacitated. This shouldn't ever happen.")
393393
return TRUE
394394

@@ -400,7 +400,7 @@ GLOBAL_LIST_EMPTY(all_grabstates)
400400
return FALSE
401401
else
402402
affecting.visible_message(span_danger("[affecting] has broken free of [assailant]'s grip!"), vision_distance = COMBAT_MESSAGE_RANGE)
403-
let_go(G)
403+
qdel(G)
404404
return TRUE
405405

406406
/datum/grab/proc/size_difference(mob/living/A, mob/living/B)

0 commit comments

Comments
 (0)