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

🆑 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.
/🆑
This commit is contained in:
MrMelbert
2026-01-05 17:27:48 -06:00
committed by GitHub
parent 537f254026
commit 156b8b0bae
3 changed files with 115 additions and 0 deletions
@@ -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)
@@ -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)
@@ -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)