//Procedures in this file: Robotic Surgery Steps ////////////////////////////////////////////////////////////////// // COMMON STEPS // ////////////////////////////////////////////////////////////////// /singleton/surgery_step/robotics can_infect = FALSE skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) /singleton/surgery_step/robotics/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE if(isslime(target)) return FALSE if(target_zone == BP_EYES) //there are specific steps for eye surgery return FALSE var/obj/item/organ/external/affected = target.get_organ(target_zone) if(isnull(affected)) return FALSE if(affected.status & ORGAN_DESTROYED) return FALSE if(!(BP_IS_ROBOTIC(affected))) return FALSE return TRUE /singleton/surgery_step/robotics/unscrew_hatch name = "Unscrew Hatch" allowed_tools = list( TOOL_SCREWDRIVER = 100, /obj/item/coin = 50, /obj/item/material/kitchen/utensil/knife = 50 ) base_surgery_time = 7 SECONDS requires_surgery_compatibility = FALSE // Basic surgery any novice roboticist can do skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_FAMILIAR) /singleton/surgery_step/robotics/unscrew_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE if(target_zone == BP_MOUTH) return FALSE var/obj/item/organ/external/affected = target.get_organ(target_zone) if(affected?.open == ORGAN_CLOSED) return TRUE return FALSE /singleton/surgery_step/robotics/unscrew_hatch/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 unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ SPAN_NOTICE("You start to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].")) ..() /singleton/surgery_step/robotics/unscrew_hatch/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("[user] has opened the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ SPAN_NOTICE("You have opened the maintenance hatch on [target]'s [affected.name] with \the [tool]."),) affected.open = ORGAN_OPEN_INCISION /singleton/surgery_step/robotics/unscrew_hatch/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 [tool.name] slips, failing to unscrew [target]'s [affected.name]."), \ SPAN_WARNING("Your [tool] slips, failing to unscrew [target]'s [affected.name].")) /singleton/surgery_step/robotics/screw_hatch name = "Screw Hatch" allowed_tools = list( TOOL_SCREWDRIVER = 100, /obj/item/coin = 50, /obj/item/material/kitchen/utensil/knife = 50 ) base_surgery_time = 7 SECONDS requires_surgery_compatibility = FALSE // Basic surgery any novice roboticist can do skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_FAMILIAR) /singleton/surgery_step/robotics/screw_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE if(target_zone == BP_MOUTH) return FALSE var/obj/item/organ/external/affected = target.get_organ(target_zone) if(affected?.open == ORGAN_OPEN_INCISION) return TRUE return FALSE /singleton/surgery_step/robotics/screw_hatch/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 screw the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ SPAN_NOTICE("You start to screw the maintenance hatch on [target]'s [affected.name] with \the [tool].")) ..() /singleton/surgery_step/robotics/screw_hatch/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("[user] has closed the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ SPAN_NOTICE("You have closed the maintenance hatch on [target]'s [affected.name] with \the [tool]."),) affected.open = ORGAN_CLOSED /singleton/surgery_step/robotics/screw_hatch/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 [tool.name] slips, failing to screw [target]'s [affected.name]."), \ SPAN_WARNING("Your [tool] slips, failing to screw [target]'s [affected.name].")) /singleton/surgery_step/robotics/open_hatch name = "Open Hatch" allowed_tools = list( TOOL_RETRACTOR = 100, TOOL_CROWBAR = 100, /obj/item/material/kitchen/utensil = 50 ) base_surgery_time = 3 SECONDS // Basic surgery any novice roboticist can do skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) /singleton/surgery_step/robotics/open_hatch/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(affected?.open == ORGAN_OPEN_INCISION) return TRUE return FALSE /singleton/surgery_step/robotics/open_hatch/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 pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].", SPAN_NOTICE("You start to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].")) ..() /singleton/surgery_step/robotics/open_hatch/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(SPAN_NOTICE("[user] opens the maintenance hatch on [target]'s [affected.name] with \the [tool]."), \ SPAN_NOTICE("You open the maintenance hatch on [target]'s [affected.name] with \the [tool].")) affected.open = ORGAN_ENCASED_RETRACTED /singleton/surgery_step/robotics/open_hatch/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 [tool.name] slips, failing to open the hatch on [target]'s [affected.name]."), SPAN_WARNING("Your [tool] slips, failing to open the hatch on [target]'s [affected.name].")) /singleton/surgery_step/robotics/close_hatch name = "Close Hatch" allowed_tools = list( TOOL_RETRACTOR = 100, TOOL_CROWBAR = 100, /obj/item/material/kitchen/utensil = 50 ) base_surgery_time = 8 SECONDS // Basic surgery any novice roboticist can do skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) /singleton/surgery_step/robotics/close_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE if(target_zone == BP_MOUTH) return FALSE var/obj/item/organ/external/affected = target.get_organ(target_zone) if(affected?.open > ORGAN_OPEN_INCISION) return TRUE return FALSE /singleton/surgery_step/robotics/close_hatch/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] begins to close the hatch on [target]'s [affected.name] with \the [tool]." , \ SPAN_NOTICE("You begin to close the hatch on [target]'s [affected.name] with \the [tool].")) ..() /singleton/surgery_step/robotics/close_hatch/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("[user] closes the hatch on [target]'s [affected.name] with \the [tool].", \ SPAN_NOTICE("You close the hatch on [target]'s [affected.name] with \the [tool].")) affected.open = ORGAN_OPEN_INCISION affected.germ_level = 0 /singleton/surgery_step/robotics/close_hatch/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 [tool.name] slips, failing to close the hatch on [target]'s [affected.name]."), SPAN_WARNING("Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].")) /singleton/surgery_step/robotics/repair_brute name = "Repair Damage" allowed_tools = list( TOOL_WELDER = 100, /obj/item/gun/energy/plasmacutter = 50 ) base_surgery_time = 4 SECONDS // Basic surgery any novice roboticist can do skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_FAMILIAR) /singleton/surgery_step/robotics/repair_brute/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(tool.tool_behaviour == TOOL_WELDER) var/obj/item/weldingtool/welder = tool if(!welder.isOn() || welder.get_fuel() < 2) return FALSE return affected && affected.open == ORGAN_ENCASED_RETRACTED && affected.brute_dam > 0 && target_zone != BP_MOUTH /singleton/surgery_step/robotics/repair_brute/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] begins to patch damage to [target]'s [affected.name]'s support structure with \the [tool]." , \ SPAN_NOTICE("You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].")) ..() /singleton/surgery_step/robotics/repair_brute/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(tool.tool_behaviour == TOOL_WELDER) var/obj/item/weldingtool/welder = tool if(!welder.isOn() && !welder.use(2, user)) user.visible_message(SPAN_WARNING("[user]'s [tool] shut off before the procedure was finished."), \ SPAN_WARNING("Your [tool] is shut off!")) return var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \ SPAN_NOTICE("You finish patching damage to [target]'s [affected.name] with \the [tool].")) affected.heal_damage(rand(30,50),0,1,1) /singleton/surgery_step/robotics/repair_brute/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 [tool.name] slips, damaging the internal structure of [target]'s [affected.name]."), SPAN_WARNING("Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].")) target.apply_damage(rand(5,10), DAMAGE_BURN, affected) /singleton/surgery_step/robotics/repair_burn name = "Repair Burns" allowed_tools = list( TOOL_CABLECOIL = 100 ) base_surgery_time = 4 SECONDS // Basic surgery any novice roboticist can do skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_FAMILIAR) /singleton/surgery_step/robotics/repair_burn/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE var/obj/item/stack/cable_coil/C = tool var/obj/item/organ/external/affected = target.get_organ(target_zone) var/limb_can_operate = (affected && affected.open == ORGAN_ENCASED_RETRACTED && affected.burn_dam > 0 && target_zone != BP_MOUTH) if(limb_can_operate) if(istype(C)) if(!C.get_amount() >= 6) to_chat(user, SPAN_DANGER("You need six or more cable pieces to repair this damage.")) return SURGERY_FAILURE C.use(3) return TRUE return FALSE /singleton/surgery_step/robotics/repair_burn/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] begins to splice new cabling into [target]'s [affected.name]." , \ SPAN_NOTICE("You begin to splice new cabling into [target]'s [affected.name].")) ..() /singleton/surgery_step/robotics/repair_burn/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("[user] finishes splicing cable into [target]'s [affected.name]", \ SPAN_NOTICE("You finishes splicing new cable into [target]'s [affected.name].")) affected.heal_damage(0,rand(30,50),1,1) /singleton/surgery_step/robotics/repair_burn/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] causes a short circuit in [target]'s [affected.name]!"), SPAN_WARNING("You cause a short circuit in [target]'s [affected.name]!")) target.apply_damage(rand(5,10), DAMAGE_BURN, affected) /singleton/surgery_step/robotics/detach_organ_robotic name = "Detach Robotic Organ" allowed_tools = list( TOOL_MULTITOOL = 100 ) base_surgery_time = 9 SECONDS skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) /singleton/surgery_step/robotics/detach_organ_robotic/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(affected.open != ORGAN_ENCASED_RETRACTED) return FALSE target.op_stage.current_organ = null var/list/attached_organs = list() for(var/organ in target.internal_organs_by_name) var/obj/item/organ/I = target.internal_organs_by_name[organ] if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) attached_organs |= organ var/organ_to_remove = tgui_input_list(user, "Which organ do you want to prepare for removal?", "Surgery", attached_organs) if(!organ_to_remove) return FALSE target.op_stage.current_organ = organ_to_remove return organ_to_remove /singleton/surgery_step/robotics/detach_organ_robotic/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] starts to decouple [target]'s [target.op_stage.current_organ] with \the [tool].", \ SPAN_NOTICE("You start to decouple [target]'s [target.op_stage.current_organ] with \the [tool]." )) ..() /singleton/surgery_step/robotics/detach_organ_robotic/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] has decoupled [target]'s [target.op_stage.current_organ] with \the [tool]." , \ SPAN_NOTICE("You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].")) var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status |= ORGAN_CUT_AWAY /singleton/surgery_step/robotics/detach_organ_robotic/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message(SPAN_WARNING("[user]'s hand slips, disconnecting \the [tool]."), \ SPAN_WARNING("Your hand slips, disconnecting \the [tool].")) /singleton/surgery_step/robotics/attach_organ_robotic name = "Attach Robotic Organ" allowed_tools = list( TOOL_SCREWDRIVER = 100 ) base_surgery_time = 10 SECONDS requires_surgery_compatibility = FALSE skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) /singleton/surgery_step/robotics/attach_organ_robotic/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(affected.open != ORGAN_ENCASED_RETRACTED) return FALSE target.op_stage.current_organ = null var/list/removable_organs = list() for(var/organ in target.internal_organs_by_name) var/obj/item/organ/I = target.internal_organs_by_name[organ] if(I && (I.status & ORGAN_CUT_AWAY) && (I.status & ORGAN_ROBOT) && I.parent_organ == target_zone) removable_organs |= organ var/organ_to_replace = tgui_input_list(user, "Which organ do you want to reattach?", "Surgery", removable_organs) if(!organ_to_replace) return FALSE target.op_stage.current_organ = organ_to_replace return TRUE /singleton/surgery_step/robotics/attach_organ_robotic/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] begins reattaching [target]'s [target.op_stage.current_organ] with \the [tool].", \ SPAN_NOTICE("You start reattaching [target]'s [target.op_stage.current_organ] with \the [tool].")) ..() /singleton/surgery_step/robotics/attach_organ_robotic/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] has reattached [target]'s [target.op_stage.current_organ] with \the [tool]." , \ SPAN_NOTICE("You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].")) var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status &= ~ORGAN_CUT_AWAY /singleton/surgery_step/robotics/attach_organ_robotic/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message(SPAN_WARNING("[user]'s hand slips, disconnecting \the [tool]."), \ SPAN_WARNING("Your hand slips, disconnecting \the [tool].")) /singleton/surgery_step/robotics/install_mmi name = "Install MMI" allowed_tools = list( /obj/item/mmi = 100 ) base_surgery_time = 6 SECONDS skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) /singleton/surgery_step/robotics/install_mmi/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE if(target_zone != BP_HEAD) return FALSE var/obj/item/mmi/M = tool var/obj/item/organ/external/affected = target.get_organ(target_zone) if(!(affected && affected.open == ORGAN_ENCASED_RETRACTED)) return FALSE if(!istype(M)) return FALSE if(!M.brainmob || !M.brainmob.client || !M.brainmob.ckey || M.brainmob.stat >= DEAD) to_chat(user, SPAN_DANGER("That brain is not usable.")) return SURGERY_FAILURE if(!BP_IS_ROBOTIC(affected)) to_chat(user, SPAN_DANGER("You cannot install a computer brain into a meat skull.")) return SURGERY_FAILURE if(!target.isSynthetic()) to_chat(user, SPAN_DANGER("You cannot install a computer brain into an organic body.")) return SURGERY_FAILURE if(!target.species) to_chat(user, SPAN_DANGER("You have no idea what species this person is. Report this on the bug tracker.")) return SURGERY_FAILURE if(!target.species.has_organ[BP_BRAIN]) to_chat(user, SPAN_DANGER("You're pretty sure [target.species.name_plural] don't normally have a brain.")) return SURGERY_FAILURE if(!isnull(target.internal_organs[BP_BRAIN])) to_chat(user, SPAN_DANGER("Your subject already has a brain.")) return SURGERY_FAILURE return TRUE /singleton/surgery_step/robotics/install_mmi/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 installing \the [tool] into [target]'s [affected.name].", \ SPAN_NOTICE("You start installing \the [tool] into [target]'s [affected.name].")) ..() /singleton/surgery_step/robotics/install_mmi/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("[user] has installed \the [tool] into [target]'s [affected.name].", \ SPAN_NOTICE("You have installed \the [tool] into [target]'s [affected.name].")) var/obj/item/mmi/M = tool var/obj/item/organ/internal/machine/posibrain/holder = new(target, 1) target.internal_organs_by_name[BP_BRAIN] = holder user.drop_from_inventory(tool,holder) holder.stored_mmi = tool holder.update_from_mmi() if(M.brainmob && M.brainmob.mind) M.brainmob.mind.transfer_to(target) /singleton/surgery_step/robotics/install_mmi/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message(SPAN_WARNING("[user]'s hand slips."), \ SPAN_WARNING("Your hand slips.")) /singleton/surgery_step/internal/fix_internal_wiring name = "Repair Internal Wiring" allowed_tools = list( TOOL_CABLECOIL = 100 ) base_surgery_time = 7 SECONDS skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) skill_diff_fail_modifier = SURGERY_DIFFICULTY_MEDIUM /singleton/surgery_step/internal/fix_internal_wiring/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) var/obj/item/stack/cable_coil/C = tool var/is_organ_damaged = FALSE var/limb_can_operate = (affected && affected.open == ORGAN_ENCASED_RETRACTED && target_zone != BP_MOUTH) if(limb_can_operate) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I.wiring.get_status() < 100) if(istype(C)) var/needed_wires = (I.wiring.max_wires - I.wiring.wires) / 2 if(needed_wires) if(!(C.get_amount() >= (needed_wires))) to_chat(user, SPAN_WARNING("You need [needed_wires] or more cable pieces to repair this damage.")) return SURGERY_FAILURE is_organ_damaged = TRUE C.use(needed_wires) return is_organ_damaged /singleton/surgery_step/internal/fix_internal_wiring/begin_step(mob/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) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I && (I.wiring.get_status() < 100)) user.visible_message(SPAN_NOTICE("[user] begins splitting and connecting new wiring in [target]'s [I]...")) ..() /singleton/surgery_step/internal/fix_internal_wiring/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) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I && (I.wiring.get_status() < 100)) var/needed_wires = I.wiring.max_wires - I.wiring.wires user.visible_message(SPAN_NOTICE("[user] fixes the wiring in [target]'s [affected].")) I.wiring.heal_damage(needed_wires) /singleton/surgery_step/internal/fix_internal_electronics name = "Repair Internal Electronics" allowed_tools = list( TOOL_MULTITOOL = 100, ) base_surgery_time = 20 SECONDS skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) skill_diff_fail_modifier = SURGERY_DIFFICULTY_HARD /singleton/surgery_step/internal/fix_internal_electronics/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) var/is_organ_damaged = FALSE var/limb_can_operate = (affected && affected.open == ORGAN_ENCASED_RETRACTED && target_zone != BP_MOUTH) if(limb_can_operate) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I.electronics.get_status() < 100) is_organ_damaged = TRUE return is_organ_damaged /singleton/surgery_step/internal/fix_internal_electronics/begin_step(mob/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) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I && (I.electronics.get_status() < 100)) user.visible_message(SPAN_NOTICE("[user] begins replacing the electronics in [target]'s [I] and reconfiguring them...")) ..() /singleton/surgery_step/internal/fix_internal_electronics/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) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I && (I.electronics.get_status() < 100)) user.visible_message(SPAN_NOTICE("[user] repairs the electronics in [target]'s [affected].")) I.electronics.heal_damage(I.electronics.max_integrity) /singleton/surgery_step/internal/fix_internal_plating name = "Repair Internal Plating" allowed_tools = list( /obj/item/stack/material/steel = 100, ) base_surgery_time = 12 SECONDS skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) skill_diff_fail_modifier = SURGERY_DIFFICULTY_HARD /singleton/surgery_step/internal/fix_internal_plating/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) var/obj/item/stack/material/steel/steel = tool var/is_organ_damaged = FALSE var/limb_can_operate = (affected && affected.open == ORGAN_ENCASED_RETRACTED && target_zone != BP_MOUTH) if(limb_can_operate) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I.plating.get_status() < 100) if(I.plating.get_status() <= 0) to_chat(user, SPAN_WARNING("That plating is too far gone! You'll need to totally replace it with new plates!")) return FALSE var/needed_plates = I.plating.max_health / 10 if(istype(steel)) if(!(steel.get_amount() >= (needed_plates))) to_chat(user, SPAN_WARNING("You need [round(needed_plates) / 10] or more steel plates to repair this damage.")) return SURGERY_FAILURE is_organ_damaged = TRUE steel.use(needed_plates) return is_organ_damaged /singleton/surgery_step/internal/fix_internal_plating/begin_step(mob/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) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I && (I.plating.get_status() < 100)) var/damage_type = pick("damage", "kinks", "gashes", "holes") user.visible_message(SPAN_NOTICE("[user] begins melding steel to the [damage_type] on the plating around [target]'s [I]..."), "You begin melding steel to the [damage_type] on the plating around [target]'s [I]...") ..() /singleton/surgery_step/internal/fix_internal_plating/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) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I && (I.plating.get_status() < 100)) user.visible_message(SPAN_NOTICE("[user] mends the plating around [target]'s [affected]."), SPAN_NOTICE("You mend the plating around [target]'s [affected].")) I.plating.heal_damage(I.plating.max_health) /singleton/surgery_step/internal/replace_internal_plating name = "Replace Internal Plating" allowed_tools = list( /obj/item/synth_plating = 100, ) base_surgery_time = 15 SECONDS skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) skill_diff_fail_modifier = SURGERY_DIFFICULTY_HARD /singleton/surgery_step/internal/replace_internal_plating/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) var/is_plating_destroyed = FALSE var/limb_can_operate = (affected && affected.open == ORGAN_ENCASED_RETRACTED && target_zone != BP_MOUTH) if(limb_can_operate) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I.plating.get_status() <= 0) is_plating_destroyed = TRUE return is_plating_destroyed /singleton/surgery_step/internal/replace_internal_plating/begin_step(mob/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) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I && (I.plating.get_status() < 100)) user.visible_message(SPAN_NOTICE("[user] begins cutting apart the old plating around [target]'s [I] and replacing it with new plates...")) ..() /singleton/surgery_step/internal/replace_internal_plating/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) for(var/obj/item/organ/internal/machine/I in affected.internal_organs) if(I && (I.plating.get_status() <= 0)) user.visible_message(SPAN_NOTICE("[user] fully replaces the plating in [target]'s [affected].")) user.remove_from_mob(tool) qdel(tool) I.plating.heal_damage(I.plating.max_health) /singleton/surgery_step/internal/replace_external_plating name = "Replace External Plating" allowed_tools = list( /obj/item/synth_plating = 100, ) base_surgery_time = 20 SECONDS var/fast_repair = FALSE skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) skill_diff_fail_modifier = SURGERY_DIFFICULTY_MEDIUM /singleton/surgery_step/internal/replace_external_plating/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE if(fast_repair) if(!istype(target.species, /datum/species/machine/industrial/hephaestus)) return FALSE var/armor_damaged = FALSE var/datum/component/armor/synthetic/synth_armor = target.GetComponent(/datum/component/armor/synthetic) if(synth_armor) var/list/damage = synth_armor.get_damage() if(length(damage)) armor_damaged = TRUE return armor_damaged /singleton/surgery_step/internal/replace_external_plating/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE user.visible_message(SPAN_NOTICE("[user] begins stripping [target]'s old armour plating and replacing it with new plates."), SPAN_NOTICE("You begin stripping off [target]'s old armour plating and replacing it with new plates.")) ..() /singleton/surgery_step/internal/replace_external_plating/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) . = ..() user.visible_message(SPAN_NOTICE("[user] finished replacing [target]'s old armour plating with new plates."), SPAN_NOTICE("You finish replacing [target]'s old armour plating with new plates.")) var/datum/component/armor/synthetic/synth_armor = target.GetComponent(/datum/component/armor/synthetic) if(istype(synth_armor)) for(var/key in synth_armor.armor_values) synth_armor.armor_values[key] = synth_armor.max_armor_values[key] qdel(tool) /singleton/surgery_step/internal/degunk name = "Remove Bio-Reactor Waste" allowed_tools = list( /obj/item/reagent_containers/glass = 100, ) base_surgery_time = 15 SECONDS skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_FAMILIAR) skill_diff_fail_modifier = SURGERY_DIFFICULTY_TRIVIAL /singleton/surgery_step/internal/replace_external_plating/g2 name = "Replace G2 External Armour Plating" base_surgery_time = 10 SECONDS fast_repair = TRUE skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) /singleton/surgery_step/internal/degunk/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) var/obj/item/organ/internal/machine/reactor/bio_reactor = target.internal_organs_by_name[BP_REACTOR] var/limb_can_operate = (affected && affected.open == ORGAN_ENCASED_RETRACTED && target_zone == BP_CHEST) if(limb_can_operate) if(bio_reactor && (bio_reactor.power_supply_type & POWER_SUPPLY_BIOLOGICAL)) var/extraneous_amount = 0 for(var/reagent_type in bio_reactor.bio_reagents.reagent_volumes) var/reagent_amount = REAGENT_VOLUME(bio_reactor.bio_reagents, reagent_type) if(!ispath(reagent_type, /singleton/reagent/nutriment)) extraneous_amount += reagent_amount if(extraneous_amount) return TRUE return FALSE /singleton/surgery_step/internal/degunk/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!..()) return FALSE user.visible_message(SPAN_NOTICE("[user] begins draining the refuse inside of [target]'s biological reactor..."), SPAN_NOTICE("You begin draining the refuse inside of [target]'s biological reactor.")) ..() /singleton/surgery_step/internal/degunk/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) . = ..() var/obj/item/organ/internal/machine/reactor/bio_reactor = target.internal_organs_by_name[BP_REACTOR] for(var/reagent_type in bio_reactor.bio_reagents.reagent_volumes) var/reagent_amount = REAGENT_VOLUME(bio_reactor.bio_reagents, reagent_type) if(!ispath(reagent_type, /singleton/reagent/nutriment)) bio_reactor.bio_reagents.trans_type_to(tool, reagent_type, reagent_amount) playsound(target, 'sound/effects/drain_blood.ogg', 50) user.visible_message(SPAN_NOTICE("[user] extracts the refuse in [target]'s biological reactor."), SPAN_NOTICE("You drain the refuse in [target]'s biological reactor to [tool].")) /singleton/surgery_step/robotics/repair_endoskeleton name = "Repair Endoskeleton" allowed_tools = list( TOOL_WELDER = 100, /obj/item/gun/energy/plasmacutter = 50 ) base_surgery_time = 2.5 SECONDS skill_requirements = alist(ROBOTICS_SKILL_COMPONENT = SKILL_LEVEL_TRAINED) skill_diff_fail_modifier = SURGERY_DIFFICULTY_MEDIUM /singleton/surgery_step/robotics/repair_endoskeleton/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(tool.tool_behaviour == TOOL_WELDER) var/obj/item/weldingtool/welder = tool if(!welder.isOn() || welder.get_fuel() < 5) return FALSE var/datum/component/synthetic_endoskeleton/endoskeleton = target.GetComponent(/datum/component/synthetic_endoskeleton) if(!istype(endoskeleton)) return FALSE return affected && affected.open == ORGAN_ENCASED_RETRACTED && affected.limb_name == BP_CHEST && target_zone != BP_MOUTH && endoskeleton.damage > 0 /singleton/surgery_step/robotics/repair_endoskeleton/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] begins to repair the support structures of [target]'s endoskeleton with \the [tool]." , \ SPAN_NOTICE("You begin to repair the support structures of [target]'s endoskeleton with \the [tool].")) ..() /singleton/surgery_step/robotics/repair_endoskeleton/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(tool.tool_behaviour == TOOL_WELDER) var/obj/item/weldingtool/welder = tool if(!welder.isOn() && !welder.use(5, user)) user.visible_message(SPAN_WARNING("[user]'s [tool] shut off before the procedure was finished."), \ SPAN_WARNING("Your [tool] is shut off!")) return user.visible_message("[user] finishes repairing some damage to [target]'s endoskeleton with \the [tool].", \ SPAN_NOTICE("You finish repairing some damage to [target]'s endoskeleton with \the [tool].")) SEND_SIGNAL(target, COMSIG_SYNTH_ENDOSKELETON_REPAIR, rand(30, 50)) /singleton/surgery_step/robotics/repair_endoskeleton/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 [tool.name] slips, damaging some of the support structure of [target]'s endoskeleton!"), SPAN_WARNING("Your [tool.name] slips, damaging some of the support structure of [target]'s endoskeleton!")) target.apply_damage(rand(5,10), DAMAGE_BURN, affected)