From 156b8b0bae8ebdaa4f5cfeddc79cb45f2e069ee2 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:27:48 -0600 Subject: [PATCH] Adds an operation for treating a dislocation, also wound surgeries get wound scanner boost (#94727) ## About The Pull Request - Adds `"reset dislocation"` operation, which effectively does everything that manually treating a dislocation does, with the same tools. - All wound surgeries now get a speed boost for treating a scanned wound ## Why It's Good For The Game - A doctor who attempts to reset a dislocated limb of a patient undergoing surgery would fail due to attempting to "operate" on the patient with the bonesetter (surgery takes priority over wound treatment). I decided the best way to fix this was to add an operation analog to the manual wound treatment. Effectively the same thing (same steps, in fact), but doing the operation form is faster and doesn't leave residual brute damage, to reward people who go through the effort. - For consistency reasons this made sense to me - scanning a wound improves manual treatment rates, so it should also apply to surgeries which treat the wound. ## Changelog :cl: Melbert add: Adds "reset dislocation" operation, which is a surgical analog to resetting a dislocated limb. Same tools, same steps, but if you go through the effort of doing it surgically, it's faster and safer. add: All wound surgeries now gain a speed bonus from being wound scanned. /:cl: --- .../operations/operation_bone_repair.dm | 97 +++++++++++++++++++ .../surgery/operations/operation_debride.dm | 6 ++ .../surgery/operations/operation_puncture.dm | 12 +++ 3 files changed, 115 insertions(+) diff --git a/code/modules/surgery/operations/operation_bone_repair.dm b/code/modules/surgery/operations/operation_bone_repair.dm index 2129d1b969e..7f9821a4493 100644 --- a/code/modules/surgery/operations/operation_bone_repair.dm +++ b/code/modules/surgery/operations/operation_bone_repair.dm @@ -1,3 +1,70 @@ +// Surgical analog to manual dislocation treatment +/datum/surgery_operation/limb/repair_dislocation + name = "reset dislocation" + desc = "Reset a dislocated bone in a patient's limb. \ + Similar to the field procedure, but quicker and safer due to being performed in a controlled environment." + operation_flags = OPERATION_PRIORITY_NEXT_STEP | OPERATION_NO_PATIENT_REQUIRED | OPERATION_AFFECTS_MOOD | OPERATION_STANDING_ALLOWED + implements = list( + TOOL_BONESET = 1, + TOOL_CROWBAR = 2, + IMPLEMENT_HAND = 5, + ) + time = 2.4 SECONDS + +/datum/surgery_operation/limb/repair_dislocation/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/blunt/bone/bone_wound in limb.wounds) + if(HAS_TRAIT(bone_wound, TRAIT_WOUND_SCANNED) && (TOOL_BONESET in bone_wound.treatable_tools)) + . *= 0.5 + +/datum/surgery_operation/limb/repair_dislocation/get_default_radial_image() + return image(/obj/item/bonesetter) + +/datum/surgery_operation/limb/repair_dislocation/all_required_strings() + return list("the limb must be dislocated") + ..() + +/datum/surgery_operation/limb/repair_dislocation/state_check(obj/item/bodypart/limb) + for(var/datum/wound/blunt/bone/bone_wound in limb.wounds) + if(TOOL_BONESET in bone_wound.treatable_tools) + return TRUE + + return FALSE + +/datum/surgery_operation/limb/repair_dislocation/on_preop(obj/item/bodypart/limb, mob/living/surgeon, obj/item/tool, list/operation_args) + display_results( + surgeon, + limb.owner, + span_notice("You begin to reset the dislocation in [FORMAT_LIMB_OWNER(limb)]..."), + span_notice("[surgeon] begins to reset the dislocation in [FORMAT_LIMB_OWNER(limb)] with [tool]."), + span_notice("[surgeon] begins to reset the dislocation in [FORMAT_LIMB_OWNER(limb)]."), + ) + display_pain(limb.owner, "Your [limb.plaintext_zone] aches with pain!") + +/datum/surgery_operation/limb/repair_dislocation/on_success(obj/item/bodypart/limb, mob/living/surgeon, obj/item/tool, list/operation_args) + for(var/datum/wound/blunt/bone/bone_wound in limb.wounds) + if(TOOL_BONESET in bone_wound.treatable_tools) + qdel(bone_wound) + + display_results( + surgeon, + limb.owner, + span_notice("You successfully reset the dislocation in [FORMAT_LIMB_OWNER(limb)]."), + span_notice("[surgeon] successfully resets the dislocation in [FORMAT_LIMB_OWNER(limb)]!"), + span_notice("[surgeon] successfully resets the dislocation in [FORMAT_LIMB_OWNER(limb)]!"), + ) + display_pain(limb.owner, "Your [limb.plaintext_zone] feels much better now!") + +/datum/surgery_operation/limb/repair_dislocation/on_failure(obj/item/bodypart/limb, mob/living/surgeon, tool, list/operation_args) + display_results( + surgeon, + limb.owner, + span_notice("You fail to reset the dislocation in [FORMAT_LIMB_OWNER(limb)], causing further damage!"), + span_notice("[surgeon] fails to reset the dislocation in [FORMAT_LIMB_OWNER(limb)], causing further damage!"), + span_notice("[surgeon] fails to reset the dislocation in [FORMAT_LIMB_OWNER(limb)]!"), + ) + display_pain(limb.owner, "The pain in your [limb.plaintext_zone] intensifies!") + limb.receive_damage(25, damage_source = tool) + /datum/surgery_operation/limb/repair_hairline name = "repair hairline fracture" desc = "Mend a hairline fracture in a patient's bone." @@ -12,6 +79,12 @@ time = 4 SECONDS any_surgery_states_required = ALL_SURGERY_SKIN_STATES +/datum/surgery_operation/limb/repair_hairline/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/blunt/bone/critical/bone_wound in limb.wounds) + if(HAS_TRAIT(bone_wound, TRAIT_WOUND_SCANNED)) + . *= 0.5 + /datum/surgery_operation/limb/repair_hairline/get_default_radial_image() return image(/obj/item/bonesetter) @@ -59,6 +132,12 @@ all_surgery_states_required = SURGERY_SKIN_OPEN any_surgery_states_blocked = SURGERY_VESSELS_UNCLAMPED +/datum/surgery_operation/limb/reset_compound/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/blunt/bone/severe/bone_wound in limb.wounds) + if(HAS_TRAIT(bone_wound, TRAIT_WOUND_SCANNED)) + . *= 0.5 + /datum/surgery_operation/limb/reset_compound/get_default_radial_image() return image(/obj/item/bonesetter) @@ -106,6 +185,12 @@ time = 4 SECONDS any_surgery_states_required = ALL_SURGERY_SKIN_STATES +/datum/surgery_operation/limb/repair_compound/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/blunt/bone/critical/bone_wound in limb.wounds) + if(HAS_TRAIT(bone_wound, TRAIT_WOUND_SCANNED)) + . *= 0.5 + /datum/surgery_operation/limb/repair_compound/get_default_radial_image() return image(/obj/item/stack/medical/bone_gel) @@ -151,6 +236,12 @@ time = 2.4 SECONDS preop_sound = 'sound/items/handling/surgery/hemostat1.ogg' +/datum/surgery_operation/limb/prepare_cranium_repair/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/cranial_fissure/fissure in limb.wounds) + if(HAS_TRAIT(fissure, TRAIT_WOUND_SCANNED)) + . *= 0.5 + /datum/surgery_operation/limb/prepare_cranium_repair/get_default_radial_image() return image(/obj/item/hemostat) @@ -190,6 +281,12 @@ ) time = 4 SECONDS +/datum/surgery_operation/limb/repair_cranium/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/cranial_fissure/fissure in limb.wounds) + if(HAS_TRAIT(fissure, TRAIT_WOUND_SCANNED)) + . *= 0.5 + /datum/surgery_operation/limb/repair_cranium/get_default_radial_image() return image(/obj/item/stack/medical/bone_gel) diff --git a/code/modules/surgery/operations/operation_debride.dm b/code/modules/surgery/operations/operation_debride.dm index de58e19a7c3..0fc0f303a6f 100644 --- a/code/modules/surgery/operations/operation_debride.dm +++ b/code/modules/surgery/operations/operation_debride.dm @@ -22,6 +22,12 @@ /// How much sanitization is added per step var/sanitization_added = 0.5 // just enough to stop infestation from worsening +/datum/surgery_operation/limb/debride/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/burn/flesh/wound in limb.wounds) + if(HAS_TRAIT(wound, TRAIT_WOUND_SCANNED)) + . *= 0.5 + /datum/surgery_operation/limb/debride/get_default_radial_image() return image(/obj/item/reagent_containers/applicator/patch/aiuri) diff --git a/code/modules/surgery/operations/operation_puncture.dm b/code/modules/surgery/operations/operation_puncture.dm index a95c4b76899..69453cbc0ae 100644 --- a/code/modules/surgery/operations/operation_puncture.dm +++ b/code/modules/surgery/operations/operation_puncture.dm @@ -11,6 +11,12 @@ operation_flags = OPERATION_AFFECTS_MOOD | OPERATION_PRIORITY_NEXT_STEP | OPERATION_NO_PATIENT_REQUIRED all_surgery_states_required = SURGERY_SKIN_OPEN|SURGERY_ORGANS_CUT +/datum/surgery_operation/limb/repair_puncture/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/pierce/bleed/pierce_wound in limb.wounds) + if(HAS_TRAIT(pierce_wound, TRAIT_WOUND_SCANNED)) + . *= 0.5 + /datum/surgery_operation/limb/repair_puncture/get_default_radial_image() return image(/obj/item/hemostat) @@ -82,6 +88,12 @@ operation_flags = OPERATION_AFFECTS_MOOD | OPERATION_PRIORITY_NEXT_STEP | OPERATION_NO_PATIENT_REQUIRED all_surgery_states_required = SURGERY_SKIN_OPEN|SURGERY_ORGANS_CUT +/datum/surgery_operation/limb/seal_veins/get_time_modifiers(obj/item/bodypart/limb, mob/living/surgeon, tool) + . = ..() + for(var/datum/wound/pierce/bleed/pierce_wound in limb.wounds) + if(HAS_TRAIT(pierce_wound, TRAIT_WOUND_SCANNED)) + . *= 0.5 + /datum/surgery_operation/limb/seal_veins/get_default_radial_image() return image(/obj/item/cautery)