mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-13 00:47:31 +01:00
0625b841c3
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>
218 lines
9.7 KiB
Plaintext
218 lines
9.7 KiB
Plaintext
//Procedures in this file: Putting items in body cavity. Implant removal. Items removal.
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// ITEM PLACEMENT SURGERY //
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
/singleton/surgery_step/cavity
|
|
priority = 1
|
|
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
|
|
|
|
/singleton/surgery_step/cavity/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 && IS_ORGAN_FULLY_OPEN && !(affected.status & ORGAN_BLEEDING)
|
|
|
|
/singleton/surgery_step/cavity/proc/get_max_wclass(var/obj/item/organ/external/affected)
|
|
switch(affected.name)
|
|
if(BP_HEAD)
|
|
return WEIGHT_CLASS_TINY
|
|
if("upper body")
|
|
return WEIGHT_CLASS_NORMAL
|
|
if("lower body")
|
|
return WEIGHT_CLASS_SMALL
|
|
return 0
|
|
|
|
/singleton/surgery_step/cavity/proc/get_cavity(var/obj/item/organ/external/affected)
|
|
switch(affected.name)
|
|
if(BP_HEAD)
|
|
return "cranial"
|
|
if("upper body")
|
|
return "thoracic"
|
|
if("lower body")
|
|
return "abdominal"
|
|
return ""
|
|
|
|
/singleton/surgery_step/cavity/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
|
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
|
|
user.visible_message(SPAN_WARNING("[user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!"), \
|
|
SPAN_WARNING("Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!"))
|
|
target.apply_damage(20, DAMAGE_BRUTE, target_zone, 0, tool, damage_flags = tool.damage_flags())
|
|
|
|
/singleton/surgery_step/cavity/make_space
|
|
name = "Hollow Out Cavity"
|
|
allowed_tools = list(
|
|
TOOL_DRILL = 100, \
|
|
/obj/item/pen = 75, \
|
|
/obj/item/stack/rods = 50
|
|
)
|
|
base_surgery_time = 7 SECONDS
|
|
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
|
|
|
|
/singleton/surgery_step/cavity/make_space/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.cavity
|
|
|
|
/singleton/surgery_step/cavity/make_space/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 making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \
|
|
"You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." )
|
|
target.custom_pain("The pain in your chest is living hell!",1)
|
|
affected.cavity = CAVITY_OPEN
|
|
..()
|
|
|
|
/singleton/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
|
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
|
|
user.visible_message("<b>[user]</b> pushes apart some organs inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \
|
|
SPAN_NOTICE("You make some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].") )
|
|
|
|
/singleton/surgery_step/cavity/close_space
|
|
name = "Close Cavity"
|
|
priority = 2
|
|
allowed_tools = list(
|
|
TOOL_CAUTERY = 100, \
|
|
/obj/item/clothing/mask/smokable/cigarette = 75, \
|
|
/obj/item/flame/lighter = 50, \
|
|
/obj/item/weldingtool = 25
|
|
)
|
|
base_surgery_time = 7 SECONDS
|
|
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
|
|
|
|
/singleton/surgery_step/cavity/close_space/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.cavity
|
|
|
|
/singleton/surgery_step/cavity/close_space/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("<b>[user]</b> starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \
|
|
"You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." )
|
|
target.custom_pain("The pain in your chest is living hell!", 75)
|
|
affected.cavity = CAVITY_CLOSED
|
|
..()
|
|
|
|
/singleton/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
|
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
|
|
user.visible_message("<b>[user]</b> mends [target]'s [get_cavity(affected)] cavity walls with \the [tool].", \
|
|
SPAN_NOTICE("You mend [target]'s [get_cavity(affected)] cavity walls with \the [tool].") )
|
|
|
|
/singleton/surgery_step/cavity/place_item
|
|
name = "Place Item in Cavity"
|
|
priority = 0
|
|
allowed_tools = list(/obj/item = 100)
|
|
base_surgery_time = 8 SECONDS
|
|
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
|
|
|
|
/singleton/surgery_step/cavity/place_item/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)
|
|
if(istype(user,/mob/living/silicon/robot))
|
|
return
|
|
if(affected && affected.cavity)
|
|
var/total_volume = tool.w_class
|
|
for(var/obj/item/I in affected.implants)
|
|
if(istype(I,/obj/item/implant))
|
|
continue
|
|
total_volume += I.w_class
|
|
return total_volume <= get_max_wclass(affected)
|
|
|
|
/singleton/surgery_step/cavity/place_item/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("<b>[user]</b> starts putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \
|
|
SPAN_NOTICE("You start putting \the [tool] inside [target]'s [get_cavity(affected)] cavity." ))
|
|
target.custom_pain("The pain in your chest is living hell!", 75)
|
|
playsound(target.loc, 'sound/effects/squelch1.ogg', 50, 1)
|
|
..()
|
|
|
|
/singleton/surgery_step/cavity/place_item/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
|
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
|
|
|
|
user.visible_message("<b>[user]</b> puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \
|
|
SPAN_NOTICE("You put \the [tool] inside [target]'s [get_cavity(affected)] cavity.") )
|
|
if(tool.w_class > get_max_wclass(affected)/2 && prob(50) && !BP_IS_ROBOTIC(affected))
|
|
to_chat(user, SPAN_WARNING("You tear \the [affected.artery_name] trying to fit an object so big!"))
|
|
affected.sever_artery()
|
|
affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1)
|
|
user.drop_item()
|
|
affected.implants += tool
|
|
tool.forceMove(affected)
|
|
affected.cavity = CAVITY_CLOSED
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// IMPLANT/ITEM REMOVAL SURGERY //
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
/singleton/surgery_step/cavity/implant_removal
|
|
name = "Remove Foreign Body"
|
|
allowed_tools = list(
|
|
TOOL_HEMOSTAT = 100, \
|
|
TOOL_WIRECUTTER = 75, \
|
|
/obj/item/material/kitchen/utensil/fork = 20
|
|
)
|
|
base_surgery_time = 8 SECONDS
|
|
skill_requirements = alist(SURGERY_SKILL_COMPONENT = SKILL_LEVEL_TRAINED)
|
|
|
|
/singleton/surgery_step/cavity/implant_removal/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
|
|
|
|
/singleton/surgery_step/cavity/implant_removal/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 poking around inside [target]'s [affected.name] with \the [tool].", \
|
|
"You start poking around inside [target]'s [affected.name] with \the [tool]." )
|
|
target.custom_pain("The pain in your [affected.name] is living hell!", 50)
|
|
..()
|
|
|
|
/singleton/surgery_step/cavity/implant_removal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
|
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
|
|
|
|
if(length(affected.implants))
|
|
var/list/implants = list()
|
|
var/shrapnel_present = FALSE
|
|
for(var/I in affected.implants)
|
|
implants += I
|
|
if(!istype(I, /obj/item/implant))
|
|
shrapnel_present = TRUE
|
|
|
|
for(var/I in implants)
|
|
/// Prioritize shrapnel instead of stuff like loyalty implants.
|
|
if(shrapnel_present && istype(I, /obj/item/implant))
|
|
continue
|
|
|
|
if(do_mob(user, target, 0.5 SECONDS))
|
|
|
|
user.visible_message("<b>[user]</b> takes [I] out of incision on [target]'s [affected.name] with \the [tool].", \
|
|
SPAN_NOTICE("You take [I] out of incision on [target]'s [affected.name]s with \the [tool].") )
|
|
target.remove_implant(I, TRUE, affected)
|
|
|
|
BITSET(target.hud_updateflag, IMPLOYAL_HUD)
|
|
|
|
//Handle possessive brain borers.
|
|
if(istype(I, /mob/living/simple_animal/borer))
|
|
var/mob/living/simple_animal/borer/worm = I
|
|
if(worm.controlling)
|
|
target.release_control()
|
|
worm.detach()
|
|
worm.leave_host()
|
|
|
|
playsound(target.loc, 'sound/effects/squelch1.ogg', 50, 1)
|
|
else
|
|
user.visible_message("<b>[user]</b> could not find anything inside [target]'s [affected.name], and pulls \the [tool] out.", \
|
|
SPAN_NOTICE("You could not find anything inside [target]'s [affected.name].") )
|
|
|
|
/singleton/surgery_step/cavity/implant_removal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
|
..()
|
|
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
|
|
user.visible_message(SPAN_WARNING("[user] loses their grip and stabs [target] with \the [tool]!"), SPAN_WARNING("You lose your grip on \the [tool] and stab [target]!"))
|
|
affected.sever_artery()
|
|
target.apply_damage(25, DAMAGE_BRUTE, target_zone)
|
|
|