Files
VMSolidus 0625b841c3 Surgery Speed Modifiers (#22472)
This PR "gently refactors" surgery doafter timers to be deterministic
and variable. Instead of being simply a random number of seconds between
an upper and lower bounds, surgeries now have a base amount of time they
take to perform (in fractional seconds). This doafter time can then be
modified via signal interactions, such as coming from components.

The Morale component, Surgery skill, Anatomy skill, and Xenobiology
skill all have had signal hooks for surgery speed added, while the
latter two are uniquely conditional signal modifiers. Anatomy only
provides its modifier if the target's species matches your own, while
Xenobiology only applies its modifier if the target is an alien. Morale
can situationally either give a bonus or a penalty depending on your
current amount of morale points.

So to offset that this is now significantly more variable and that 4
different sources of bonus surgical speed exist, I've actually made the
base surgery times always on the upper end of what their previous
doafter duration range was, so surgeries are in general slower if you
aren't taking advantage of specializing in it.

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
2026-06-19 16:47:29 +00:00

153 lines
8.4 KiB
Plaintext

//Procedures in this file: Fracture repair surgery
//////////////////////////////////////////////////////////////////
// BONE SURGERY //
//////////////////////////////////////////////////////////////////
/singleton/surgery_step/glue_bone
name = "Repair Broken Bone"
allowed_tools = list(
/obj/item/surgery/bone_gel = 100, \
/obj/item/tape_roll = 60
)
can_infect = TRUE
blood_level = 1
base_surgery_time = 4 SECONDS
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
/singleton/surgery_step/glue_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(!..())
return FALSE
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return affected && !BP_IS_ROBOTIC(affected) && affected.open >= ORGAN_OPEN_RETRACTED && affected.open < ORGAN_ENCASED_RETRACTED && affected.stage == BONE_PRE_OP && (affected.status & ORGAN_BROKEN)
/singleton/surgery_step/glue_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if (affected.stage == BONE_PRE_OP)
user.visible_message("<b>[user]</b> starts applying some of [tool] to the damaged bones in [target]'s [affected.name]." , \
SPAN_NOTICE("You start applying some of [tool] to the damaged bones in [target]'s [affected.name]."))
target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1)
..()
/singleton/surgery_step/glue_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<b>[user]</b> applies some of [tool] to [target]'s bone in [affected.name].", \
SPAN_NOTICE("You apply some of [tool] to [target]'s bone in [affected.name]."))
affected.stage = BONE_GLUED
/singleton/surgery_step/glue_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(SPAN_WARNING("[user]'s hand slips, smearing some of [tool] in the incision in [target]'s [affected.name]!") , \
SPAN_WARNING("Your hand slips, smearing some of [tool] in the incision in [target]'s [affected.name]!"))
target.apply_damage(15, DAMAGE_PAIN)
/singleton/surgery_step/set_bone
name = "Set Broken Bone"
allowed_tools = list(
TOOL_BONESET = 100, \
TOOL_WRENCH = 75 \
)
base_surgery_time = 5 SECONDS
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
/singleton/surgery_step/set_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(!..())
return FALSE
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return affected && affected.name != BP_HEAD && !BP_IS_ROBOTIC(affected) && affected.open >= ORGAN_OPEN_RETRACTED && affected.stage == BONE_GLUED
/singleton/surgery_step/set_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] is beginning to set the bone in [target]'s [affected.name] in place with \the [tool]." , \
"You are beginning to set the bone in [target]'s [affected.name] in place with \the [tool].")
target.custom_pain("The pain in your [affected.name] is going to make you pass out!",1)
..()
/singleton/surgery_step/set_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(affected.status & ORGAN_BROKEN)
user.visible_message("<b>[user]</b> sets the bone in [target]'s [affected.name] in place with \the [tool].", \
SPAN_NOTICE("You set the bone in [target]'s [affected.name] in place with \the [tool]."))
affected.stage = BONE_SET
else
user.visible_message(SPAN_NOTICE("[user] sets the bone in [target]'s [affected.name] [SPAN_WARNING("in the WRONG place with \the [tool].")]"), \
SPAN_NOTICE("You set the bone in [target]'s [affected.name] [SPAN_WARNING("in the WRONG place with \the [tool].")]"))
affected.fracture()
/singleton/surgery_step/set_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(SPAN_WARNING("[user]'s hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!") , \
SPAN_WARNING("Your hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!"))
target.apply_damage(5, DAMAGE_BRUTE, target_zone, 0, tool, damage_flags = tool.damage_flags())
/singleton/surgery_step/mend_skull
name = "Repair Broken Skull"
allowed_tools = list(
TOOL_BONESET = 100, \
TOOL_WRENCH = 75 \
)
base_surgery_time = 5 SECONDS
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
/singleton/surgery_step/mend_skull/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(!..())
return FALSE
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return affected && affected.name == BP_HEAD && !BP_IS_ROBOTIC(affected) && affected.open >= ORGAN_OPEN_RETRACTED && affected.stage == BONE_GLUED
/singleton/surgery_step/mend_skull/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("[user] is beginning to piece together [target]'s skull with \the [tool]." , \
"You are beginning to piece together [target]'s skull with \the [tool].")
..()
/singleton/surgery_step/mend_skull/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<b>[user]</b> sets [target]'s skull with \the [tool]." , \
SPAN_NOTICE("You set [target]'s skull with \the [tool]."))
affected.stage = ORGAN_OPEN_RETRACTED
/singleton/surgery_step/mend_skull/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(SPAN_WARNING("[user]'s hand slips, damaging [target]'s face with \the [tool]!") , \
SPAN_WARNING("Your hand slips, damaging [target]'s face with \the [tool]!"))
var/obj/item/organ/external/head/h = affected
target.apply_damage(10, DAMAGE_BRUTE, target_zone, 0, tool, damage_flags = tool.damage_flags())
h.disfigured = 1
/singleton/surgery_step/finish_bone
name = "Finish Repairing Broken Bone"
allowed_tools = list(
/obj/item/surgery/bone_gel = 100, \
/obj/item/tape_roll = 60
)
can_infect = TRUE
blood_level = 1
base_surgery_time = 4 SECONDS
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
/singleton/surgery_step/finish_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(!..())
return FALSE
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return affected && affected.open >= ORGAN_OPEN_RETRACTED && affected.open < ORGAN_ENCASED_RETRACTED && !BP_IS_ROBOTIC(affected) && affected.stage == BONE_SET
/singleton/surgery_step/finish_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].", \
"You start to finish mending the damaged bones in [target]'s [affected.name] with \the [tool].")
..()
/singleton/surgery_step/finish_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("<b>[user]</b> has mended the damaged bones in [target]'s [affected.name] with \the [tool]." , \
SPAN_NOTICE("You have mended the damaged bones in [target]'s [affected.name] with \the [tool].") )
affected.status &= ~ORGAN_BROKEN
affected.status &= ~ORGAN_SPLINTED
affected.stage = BONE_PRE_OP
affected.perma_injury = 0
/singleton/surgery_step/finish_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(SPAN_WARNING("[user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") , \
SPAN_WARNING("Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!"))
target.apply_damage(15, DAMAGE_PAIN)