Skip to content

Surgery changes and fixes #1007

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

Merged
merged 12 commits into from
Jun 30, 2024
Merged
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
7 changes: 7 additions & 0 deletions code/__DEFINES/surgery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@
#define SURGERY_NEEDS_RETRACTED (1<<4)
/// Bodypart needs a broken bone AND retracted incision or large cut
#define SURGERY_NEEDS_DEENCASEMENT (1<<5)
/// Surgery step bloodies gloves when necessary.
#define SURGERY_BLOODY_GLOVES (1<<6)
/// Surgery step bloodies gloves + suit when necessary.
#define SURGERY_BLOODY_BODY (1<<7)
/// Surgery does not use RNG.
#define SURGERY_CANNOT_FAIL (1<<8)

/// Only one of this type of implant may be in a target
#define IMPLANT_HIGHLANDER (1<<0)
/// Shows implant name in body scanner
#define IMPLANT_KNOWN (1<<1)
/// Hides the implant from the body scanner completely
#define IMPLANT_HIDDEN (1<<2)

2 changes: 0 additions & 2 deletions code/__HELPERS/global_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@
if(!isabstract(path))
path = new path()
GLOB.surgeries_list += path
if(!length(path.allowed_tools))
stack_trace("Surgery type [path.type] has no allowed_items list.")

sort_list(GLOB.surgeries_list, GLOBAL_PROC_REF(cmp_typepaths_asc))

Expand Down
4 changes: 2 additions & 2 deletions code/__HELPERS/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
return GET_BLOOD_REF(path)

/proc/get_blood_dna_color(list/blood_dna)
var/datum/blood/blood_type = blood_dna[blood_dna[length(blood_dna)]]
return blood_type.color
var/datum/blood/blood_type = blood_dna?[blood_dna[length(blood_dna)]]
return blood_type?.color

/proc/random_eye_color()
switch(pick(20;"brown",20;"hazel",20;"grey",15;"blue",15;"green",1;"amber",1;"albino"))
Expand Down
22 changes: 22 additions & 0 deletions code/__HELPERS/type2type.dm
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,28 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,
if(ITEM_SLOT_LEGCUFFED)
return pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)

/proc/body_zone2item_slots(zone)
switch(zone)
if(BODY_ZONE_HEAD)
return ITEM_SLOT_HEAD|ITEM_SLOT_MASK

if(BODY_ZONE_PRECISE_EYES)
return ITEM_SLOT_EYES

if(BODY_ZONE_CHEST)
return ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING

if(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM)
return ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING|ITEM_SLOT_GLOVES

if(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND)
return ITEM_SLOT_GLOVES

if(BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
return ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING|ITEM_SLOT_FEET

if(BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT)
return ITEM_SLOT_FEET
//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
/proc/heat2colour(temp)
return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp))
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
/mob/living/attackby(obj/item/attacking_item, mob/living/user, params)
if(..())
return TRUE
if (user.can_operate_on(src) && attacking_item.attempt_surgery(src, user))
if (user.can_perform_surgery_on(src) && attacking_item.attempt_surgery(src, user))
return TRUE

user.changeNext_move(attacking_item.combat_click_delay)
Expand Down
12 changes: 11 additions & 1 deletion code/datums/components/bloodysoles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,17 @@
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
return TRUE

parent_atom.add_blood_DNA(pool.return_blood_DNA())
if(ishuman(parent_atom))
var/bloody_slots = ITEM_SLOT_OCLOTHING|ITEM_SLOT_ICLOTHING|ITEM_SLOT_FEET
var/mob/living/carbon/human/to_bloody = parent_atom
if(to_bloody.body_position == LYING_DOWN)
bloody_slots |= ITEM_SLOT_HEAD|ITEM_SLOT_MASK|ITEM_SLOT_GLOVES

to_bloody.add_blood_DNA_to_items(pool.return_blood_DNA(), bloody_slots)

else
parent_atom.add_blood_DNA(pool.return_blood_DNA())

if(pool.bloodiness <= 0)
qdel(pool)

Expand Down
5 changes: 3 additions & 2 deletions code/datums/forensics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@
parent = null
return ..()

/// Adds blood dna. Returns TRUE if the blood dna list expanded.
/datum/forensics/proc/add_blood_DNA(list/dna)
if(!length(dna))
return

var/old_len = length(blood_DNA)
LAZYINITLIST(blood_DNA)
for(var/dna_hash in dna)
blood_DNA[dna_hash] = dna[dna_hash]

check_blood()
return TRUE
return old_len < length(blood_DNA)

/datum/forensics/proc/add_trace_DNA(list/dna)
if(!length(dna))
Expand Down
7 changes: 7 additions & 0 deletions code/game/objects/effects/decals/cleanable/humans.dm
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@
if(!is_dry)
color = blood_color

/obj/effect/decal/cleanable/blood/attack_hand(mob/living/user, list/modifiers)
. = ..()
if(ishuman(user) && blood_DNA_length())
var/mob/living/carbon/human/H = user
H.add_blood_DNA_to_items(return_blood_DNA(), ITEM_SLOT_GLOVES)
H.visible_message(span_notice("[user.name] runs [H.p_their()] fingers through [src]."))

/obj/effect/decal/cleanable/blood/proc/get_timer()
drytime = world.time + dry_duration

Expand Down
2 changes: 1 addition & 1 deletion code/modules/clothing/gloves/_gloves.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

/obj/item/clothing/gloves/worn_overlays(mob/living/carbon/human/wearer, mutable_appearance/standing, isinhands = FALSE)
. = ..()
if(!isinhands)
if(isinhands)
return

if(damaged_clothes)
Expand Down
20 changes: 11 additions & 9 deletions code/modules/codex/categories/surgery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,25 @@
for(var/datum/surgery_step/step as anything in GLOB.surgeries_list)
var/list/info = list("<ul>")

var/obj/path_or_tool = step.allowed_tools[1]
info += "<li>Best performed with \a [istext(path_or_tool) ? "[path_or_tool]" : "[initial(path_or_tool.name)]"].</li>"
if(!step.surgery_candidate_flags)
var/obj/path_or_tool = step.allowed_tools?[1]
if(path_or_tool)
info += "<li>Best performed with \a [istext(path_or_tool) ? "[path_or_tool]" : "[initial(path_or_tool.name)]"].</li>"

if(!(step.surgery_flags & ~(SURGERY_CANNOT_FAIL | SURGERY_BLOODY_BODY | SURGERY_BLOODY_GLOVES)))
info += "<li>This operation has no requirements."
else
if(step.surgery_candidate_flags & SURGERY_NO_FLESH)
if(step.surgery_flags & SURGERY_NO_FLESH)
info += "<li>This operation cannot be performed on organic limbs."
else if(step.surgery_candidate_flags & SURGERY_NO_ROBOTIC)
else if(step.surgery_flags & SURGERY_NO_ROBOTIC)
info += "<li>This operation cannot be performed on robotic limbs."

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

info += "</ul>"
Expand Down
72 changes: 46 additions & 26 deletions code/modules/detectivework/detective_work.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,14 @@
/// Adds the fibers of M to our fiber list.
/atom/proc/add_fibers(mob/living/carbon/human/M)
if(istype(M))
var/old = 0
if(M.gloves && istype(M.gloves, /obj/item/clothing))
var/obj/item/clothing/gloves/G = M.gloves
old = length(G.return_blood_DNA())

if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
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
G.transfer_blood--
if(G.transfer_blood > 1 && add_blood_DNA(G.return_blood_DNA())) //bloodied gloves transfer blood to touched objects
G.transfer_blood--

else if(M.blood_in_hands > 1)
old = length(M.return_blood_DNA())
if(add_blood_DNA(M.return_blood_DNA()) && length(M.return_blood_DNA()) > old)
M.blood_in_hands--
else if(M.blood_in_hands > 1 && add_blood_DNA(M.return_blood_DNA()))
M.blood_in_hands--

if(isnull(forensics))
create_forensics()
Expand Down Expand Up @@ -99,6 +94,7 @@

forensics.add_trace_DNA(dna)

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

Expand All @@ -109,8 +105,7 @@
if(isnull(forensics))
create_forensics()

forensics.add_blood_DNA(dna)
return TRUE
return forensics.add_blood_DNA(dna)

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

if(!QDELETED(B))
B.add_blood_DNA(blood_dna) //give blood info to the blood decal.
return TRUE //we bloodied the floor
return B.add_blood_DNA(blood_dna) //give blood info to the blood decal.

/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
if(wear_suit)
wear_suit.add_blood_DNA(blood_dna)
update_worn_oversuit()
return add_blood_DNA_to_items(blood_dna)

/// Adds blood DNA to certain slots the mob is wearing
/mob/living/carbon/human/proc/add_blood_DNA_to_items(
list/blood_DNA_to_add,
target_flags = ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING|ITEM_SLOT_GLOVES|ITEM_SLOT_HEAD|ITEM_SLOT_MASK,
)
if(QDELING(src))
return FALSE

if(!length(blood_DNA_to_add))
return FALSE

// Don't messy up our jumpsuit if we're got a coat
if((obscured_slots & HIDEJUMPSUIT) || ((target_flags & ITEM_SLOT_OCLOTHING) && (wear_suit?.body_parts_covered & CHEST)))
target_flags &= ~ITEM_SLOT_ICLOTHING

var/dirty_hands = !!(target_flags & (ITEM_SLOT_GLOVES|ITEM_SLOT_HANDS))
var/dirty_feet = !!(target_flags & ITEM_SLOT_FEET)
var/slots_to_bloody = target_flags & ~check_obscured_slots()
var/list/all_worn = get_equipped_items()

else if(w_uniform)
w_uniform.add_blood_DNA(blood_dna)
update_worn_undersuit()
for(var/obj/item/thing as anything in all_worn)
if(thing.slot_flags & slots_to_bloody)
thing.add_blood_DNA(blood_DNA_to_add)

if(gloves)
var/obj/item/clothing/gloves/G = gloves
G.add_blood_DNA(blood_dna)
if(thing.body_parts_covered & HANDS)
dirty_hands = FALSE

else if(length(blood_dna))
if(thing.body_parts_covered & FEET)
dirty_feet = FALSE

if(slots_to_bloody & ITEM_SLOT_HANDS)
for(var/obj/item/thing in held_items)
thing.add_blood_DNA(blood_DNA_to_add)

if(dirty_hands || dirty_feet || !length(all_worn))
if(isnull(forensics))
create_forensics()
forensics.add_blood_DNA(blood_dna)
forensics.add_blood_DNA(blood_DNA_to_add)

update_worn_gloves() //handles bloody hands overlays and updating
return TRUE
if(dirty_hands)
blood_in_hands = max(blood_in_hands, rand(2, 4))

update_clothing(slots_to_bloody)
return TRUE
/*
* Transfer all forensic evidence from [src] to [transfer_to].
*/
Expand Down
4 changes: 2 additions & 2 deletions code/modules/grab/grab_datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ GLOBAL_LIST_EMPTY(all_grabstates)
return FALSE

if (assailant.incapacitated(IGNORE_GRAB))
let_go(G)
qdel(G)
stack_trace("Someone resisted a grab while the assailant was incapacitated. This shouldn't ever happen.")
return TRUE

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

/datum/grab/proc/size_difference(mob/living/A, mob/living/B)
Expand Down
Loading
Loading