/datum/surgery/cavity_implant
name = "Cavity Implant/Removal"
steps = list(
/datum/surgery_step/generic/cut_open,
/datum/surgery_step/generic/clamp_bleeders,
/datum/surgery_step/generic/retract_skin,
/datum/surgery_step/proxy/ib, // just do IB here since we're sawing the bone anyway
/datum/surgery_step/open_encased/saw,
/datum/surgery_step/open_encased/retract,
/datum/surgery_step/cavity/make_space,
/datum/surgery_step/proxy/cavity_manipulation,
/datum/surgery_step/cavity/close_space,
/datum/surgery_step/open_encased/close,
/datum/surgery_step/glue_bone,
/datum/surgery_step/set_bone,
/datum/surgery_step/finish_bone,
/datum/surgery_step/generic/cauterize
)
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)
/datum/surgery/cavity_implant/can_start(mob/user, mob/living/carbon/target)
if(HAS_TRAIT(target, TRAIT_NO_BONES))
return FALSE
return TRUE
/datum/surgery/cavity_implant/soft
desc = "Implant an object into a cavity not protected by bone."
steps = list(
/datum/surgery_step/generic/cut_open,
/datum/surgery_step/generic/clamp_bleeders,
/datum/surgery_step/generic/retract_skin,
/datum/surgery_step/proxy/ib, // just do IB here since we're sawing the bone anyway
/datum/surgery_step/generic/cut_open,
/datum/surgery_step/cavity/make_space,
/datum/surgery_step/proxy/cavity_manipulation,
/datum/surgery_step/cavity/close_space,
/datum/surgery_step/generic/cauterize
)
possible_locs = list(BODY_ZONE_PRECISE_GROIN)
/datum/surgery/cavity_implant/soft/boneless
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)
/datum/surgery/cavity_implant/soft/boneless/can_start(mob/user, mob/living/carbon/target)
if(!HAS_TRAIT(target, TRAIT_NO_BONES))
return FALSE
return TRUE
/datum/surgery/cavity_implant/synth
name = "Robotic Cavity Implant/Removal"
steps = list(
/datum/surgery_step/robotics/external/unscrew_hatch,
/datum/surgery_step/robotics/external/open_hatch,
/datum/surgery_step/proxy/cavity_manipulation/robotic,
/datum/surgery_step/cavity/close_space/synth,
/datum/surgery_step/robotics/external/close_hatch
)
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN)
requires_organic_bodypart = FALSE
/datum/surgery_step/proxy/cavity_manipulation
name = "Cavity Manipulation (proxy)"
branches = list(
/datum/surgery/intermediate/open_cavity/implant,
/datum/surgery/intermediate/open_cavity/extract,
/datum/surgery/intermediate/bleeding
)
insert_self_after = TRUE
/datum/surgery_step/proxy/cavity_manipulation/robotic
name = "Robotic Cavity Manipulation (proxy)"
branches = list(
/datum/surgery/intermediate/open_cavity/implant/robotic,
/datum/surgery/intermediate/open_cavity/extract/robotic
)
/datum/surgery/intermediate/open_cavity
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)
/datum/surgery/intermediate/open_cavity/implant
name = "implant object"
steps = list(
/datum/surgery_step/cavity/place_item
)
/datum/surgery/intermediate/open_cavity/extract
name = "extract object"
steps = list(
/datum/surgery_step/cavity/remove_item
)
/datum/surgery/intermediate/open_cavity/implant/robotic
requires_organic_bodypart = FALSE
/datum/surgery/intermediate/open_cavity/extract/robotic
requires_organic_bodypart = FALSE
/datum/surgery_step/cavity
/datum/surgery_step/cavity/proc/get_max_wclass(obj/item/organ/external/affected)
switch(affected.limb_name)
if(BODY_ZONE_HEAD)
return WEIGHT_CLASS_TINY
if(BODY_ZONE_CHEST)
return WEIGHT_CLASS_NORMAL
if(BODY_ZONE_PRECISE_GROIN)
return WEIGHT_CLASS_SMALL
return 0
/datum/surgery_step/cavity/proc/get_cavity(obj/item/organ/external/affected)
switch(affected.limb_name)
if(BODY_ZONE_HEAD)
return "cranial"
if(BODY_ZONE_CHEST)
return "thoracic"
if(BODY_ZONE_PRECISE_GROIN)
return "abdominal"
return ""
/datum/surgery_step/cavity/proc/get_item_inside(obj/item/organ/external/affected)
var/obj/item/extracting
for(var/obj/item/I in affected.contents)
if(!istype(I, /obj/item/organ))
extracting = I
break
if(!extracting && affected.hidden)
extracting = affected.hidden
return extracting
/datum/surgery_step/cavity/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
user.visible_message(
"[user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!",
"Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!",
chat_message_type = MESSAGE_TYPE_COMBAT
)
affected.receive_damage(20)
return SURGERY_STEP_RETRY
/datum/surgery_step/cavity/make_space
name = "make cavity space"
allowed_tools = list(
TOOL_DRILL = 100,
/obj/item/screwdriver/power = 90,
/obj/item/pen = 90,
/obj/item/stack/rods = 60
)
preop_sound = list(
TOOL_DRILL = 'sound/items/drill_hit.ogg',
/obj/item/screwdriver/power = 'sound/items/drill_hit.ogg',
/obj/item/pen = 'sound/surgery/organ2.ogg',
/obj/item/stack/rods = 'sound/surgery/organ2.ogg'
)
time = 5.4 SECONDS
/datum/surgery_step/cavity/make_space/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
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].",
chat_message_type = MESSAGE_TYPE_COMBAT
)
affected.custom_pain("The pain in your chest is living hell!")
return ..()
/datum/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
user.visible_message(
"[user] makes some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].",
"You make some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].",
chat_message_type = MESSAGE_TYPE_COMBAT
)
return SURGERY_STEP_CONTINUE
/datum/surgery_step/cavity/close_space
name = "close cavity space"
allowed_tools = list(
/obj/item/scalpel/laser = 100,
TOOL_CAUTERY = 100,
/obj/item/clothing/mask/cigarette = 90,
/obj/item/lighter = 60,
TOOL_WELDER = 30
)
preop_sound = 'sound/surgery/cautery1.ogg'
success_sound = 'sound/surgery/cautery2.ogg'
failure_sound = 'sound/items/welder.ogg'
time = 2.4 SECONDS
/datum/surgery_step/cavity/close_space/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(
"[user] 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].",
chat_message_type = MESSAGE_TYPE_COMBAT
)
affected.custom_pain("The pain in your chest is living hell!")
return ..()
/datum/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
user.visible_message(
"[user] mends [target]'s [get_cavity(affected)] cavity walls with \the [tool].",
"You mend [target]'s [get_cavity(affected)] cavity walls with \the [tool].",
chat_message_type = MESSAGE_TYPE_COMBAT
)
return SURGERY_STEP_CONTINUE
/datum/surgery_step/cavity/close_space/synth
name = "seal cavity"
allowed_tools = list(
TOOL_WELDER = 100,
/obj/item/scalpel/laser = 60,
TOOL_CAUTERY = 50,
/obj/item/lighter = 30,
)
/datum/surgery_step/cavity/remove_item
name = "extract object"
accept_hand = TRUE
/datum/surgery_step/cavity/remove_item/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
// Check even if there isn't anything inside
user.visible_message(
"[user] checks for items in [target]'s [target_zone].",
"You check for items in [target]'s [target_zone]...",
chat_message_type = MESSAGE_TYPE_COMBAT
)
return ..()
/datum/surgery_step/cavity/remove_item/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/extracting
var/obj/item/organ/external/affected = target.get_organ(target_zone)
extracting = get_item_inside(affected)
if(!extracting)
to_chat(user, "You don't find anything in [target]'s [target_zone].")
return SURGERY_STEP_CONTINUE
user.visible_message(
"[user] pulls [extracting] out of [target]'s [target_zone]!",
"You pull [extracting] out of [target]'s [target_zone].",
chat_message_type = MESSAGE_TYPE_COMBAT
)
user.put_in_hands(extracting)
if(extracting == affected.hidden)
affected.hidden = null
return SURGERY_STEP_CONTINUE
/datum/surgery_step/cavity/remove_item/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(
"[user] grabs onto something else by mistake, damaging it!.",
"You grab onto something else inside [target]'s [get_cavity(affected)] cavity by mistake, damaging it!",
chat_message_type = MESSAGE_TYPE_COMBAT
)
affected.damage += rand(3, 5)
return SURGERY_STEP_INCOMPLETE
/datum/surgery_step/cavity/place_item
name = "implant object"
accept_any_item = TRUE
time = 3.2 SECONDS
/datum/surgery_step/cavity/place_item/tool_check(mob/user, obj/item/tool)
if(istype(tool, /obj/item/disk/nuclear))
to_chat(user, "Central command would kill you if you implanted the disk into someone.")
return FALSE
var/obj/item/disk/nuclear/datdisk = locate() in tool
if(datdisk)
to_chat(user, "Central Command would kill you if you implanted the disk into someone. Especially if in a [tool].")
return FALSE
if(istype(tool, /obj/item/organ))
to_chat(user, "This isn't the type of surgery for organ transplants!")
return FALSE
if(!user.canUnEquip(tool, 0))
to_chat(user, "[tool] is stuck to your hand!")
return FALSE
if(istype(tool, /obj/item/cautery))
// Pass it to the next step
return FALSE
return TRUE
/datum/surgery_step/cavity/place_item/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
var/can_fit = !affected.hidden && tool.w_class <= get_max_wclass(affected)
if(!can_fit)
to_chat(user, "\The [tool] won't fit in \the [affected]!")
return SURGERY_BEGINSTEP_SKIP
user.visible_message(
"[user] starts putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.",
"You start putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.",
chat_message_type = MESSAGE_TYPE_COMBAT
)
affected.custom_pain("The pain in your [target_zone] is living hell!")
return ..()
/datum/surgery_step/cavity/place_item/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
if(get_item_inside(affected))
to_chat(user, "There seems to be something in there already!")
return SURGERY_STEP_CONTINUE
user.visible_message(
"[user] puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.",
"You put \the [tool] inside [target]'s [get_cavity(affected)] cavity.",
chat_message_type = MESSAGE_TYPE_COMBAT
)
if((tool.w_class > get_max_wclass(affected) / 2 && prob(50) && !affected.is_robotic()))
user.visible_message(
"[user] tears some blood vessels trying to fit the object in the cavity!",
"You tear some blood vessels trying to fit the object into the cavity!",
"You hear some gentle tearing.", MESSAGE_TYPE_COMBAT)
affected.cause_internal_bleeding()
user.drop_item()
affected.hidden = tool
tool.forceMove(target)
return SURGERY_STEP_CONTINUE