diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 4efec263f80..1d45a3e508b 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -184,7 +184,7 @@ /obj/machinery/computer/operating/proc/build_surgery_list(mob/user) if(!istype(victim)) return null - + . = list() for(var/limb in victim.organs_by_name) @@ -281,6 +281,7 @@ /datum/surgery_step/cavity, /datum/surgery_step/limb, /datum/surgery_step/brainstem, + /datum/surgery_step/generic/ripper, ) good_surgeries = surgery_steps for(var/datum/surgery_step/S in good_surgeries) diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index 48ced948be8..260646f1ec6 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -134,8 +134,8 @@ force = 7.5 /obj/item/weapon/surgical/scalpel/ripper - name = "organ pincers" - desc = "A horrifying bladed tool with a large metal spike in its center. The tool is used for rapidly removing organs from hopefully willing patients." + name = "jagged scalpel" + desc = "A horrifying bladed tool with a large metal spike in its center. The tool is used for rapidly removing organs or medical malpractice." icon_state = "organ_ripper" item_state = "bone_setter" force = 15.0 diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm index d6181cf126f..b372ae1917a 100644 --- a/code/game/objects/items/weapons/tools/weldingtool.dm +++ b/code/game/objects/items/weapons/tools/weldingtool.dm @@ -92,6 +92,8 @@ if(S.robo_repair(15, BRUTE, "some dents", src, user)) remove_fuel(1, user) return 1 + else + return 1 //Stops you from accidentally harming someone while on help intent. return ..() diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index 6a48eb198dd..1a0bd6271b6 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/glue_bone + surgery_name = "Glue Bone" allowed_tools = list( /obj/item/weapon/surgical/bonegel = 100 ) @@ -52,6 +53,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/set_bone + surgery_name = "Set Bone" allowed_tools = list( /obj/item/weapon/surgical/bonesetter = 100 ) @@ -98,6 +100,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/mend_skull + surgery_name = "Mend Skull" allowed_tools = list( /obj/item/weapon/surgical/bonesetter = 100 ) @@ -139,6 +142,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/finish_bone + surgery_name = "Finish Mending Bone" allowed_tools = list( /obj/item/weapon/surgical/bonegel = 100 ) @@ -182,6 +186,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/clamp_bone + surgery_name = "Clamp Bone" allowed_tools = list( /obj/item/weapon/surgical/bone_clamp = 100 ) @@ -218,4 +223,4 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user]'s hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!" , \ "Your hand slips, damaging the bone in [target]'s [affected.name] with \the [tool]!") - affected.createwound(BRUISE, 5) \ No newline at end of file + affected.createwound(BRUISE, 5) diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm index d69c456f7ce..f41e33500e5 100644 --- a/code/modules/surgery/encased.dm +++ b/code/modules/surgery/encased.dm @@ -3,6 +3,7 @@ // GENERIC RIBCAGE SURGERY // ////////////////////////////////////////////////////////////////// /datum/surgery_step/open_encased + surgery_name = "Open Encased" priority = 2 can_infect = 1 blood_level = 1 @@ -21,6 +22,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/open_encased/saw + surgery_name = "Cut Bone" allowed_tools = list( /obj/item/weapon/surgical/circular_saw = 100, \ /obj/item/weapon/material/knife/machete/hatchet = 75 @@ -70,6 +72,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/open_encased/retract + surgery_name = "Retract Ribs Open" allowed_tools = list( /obj/item/weapon/surgical/retractor = 100 ) @@ -123,6 +126,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/open_encased/close + surgery_name = "Retract Ribs Closed" allowed_tools = list( /obj/item/weapon/surgical/retractor = 100, ) @@ -181,6 +185,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/open_encased/mend + surgery_name = "Mend Ribs" allowed_tools = list( /obj/item/weapon/surgical/bonegel = 100 ) @@ -222,6 +227,7 @@ // Saw/Retractor/Gel Combi-open and close. /////////////////////////////////////////////////////////////// /datum/surgery_step/open_encased/advancedsaw_open + surgery_name = "Advanced Cut Ribs" allowed_tools = list( /obj/item/weapon/surgical/circular_saw/manager = 100 ) @@ -230,6 +236,7 @@ min_duration = 60 max_duration = 90 + excludes_steps = list(/datum/surgery_step/open_encased/saw) /datum/surgery_step/open_encased/advancedsaw_open/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if (!hasorgans(target)) @@ -271,6 +278,7 @@ /datum/surgery_step/open_encased/advancedsaw_mend + surgery_name = "Advanced Mend Ribs" allowed_tools = list( /obj/item/weapon/surgical/circular_saw/manager = 100 ) diff --git a/code/modules/surgery/external_repair.dm b/code/modules/surgery/external_repair.dm index 4f8707e82d9..820ae4e5593 100644 --- a/code/modules/surgery/external_repair.dm +++ b/code/modules/surgery/external_repair.dm @@ -3,6 +3,7 @@ // LIMB REPAIR SURGERY // ////////////////////////////////////////////////////////////////// /datum/surgery_step/repairflesh/ + surgery_name = "Repair Flesh" priority = 1 can_infect = 1 blood_level = 1 @@ -36,6 +37,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/repairflesh/scan_injury + surgery_name = "Scan Injury" allowed_tools = list( /obj/item/weapon/autopsy_scanner = 100, /obj/item/device/analyzer = 10 @@ -86,6 +88,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/repairflesh/repair_burns + surgery_name = "Repair Burns" allowed_tools = list( /obj/item/stack/medical/advanced/ointment = 100, /obj/item/stack/medical/ointment = 50, @@ -152,6 +155,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/repairflesh/repair_brute + surgery_name = "Repair Brute" allowed_tools = list( /obj/item/stack/medical/advanced/bruise_pack = 100, /obj/item/stack/medical/bruise_pack = 50, diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm index fc10ecfcca4..9ecef802522 100644 --- a/code/modules/surgery/face.dm +++ b/code/modules/surgery/face.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/face + surgery_name = "Facial Surgery" priority = 2 req_open = 0 can_infect = 0 @@ -23,6 +24,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/generic/cut_face + surgery_name = "Cut Face" allowed_tools = list( /obj/item/weapon/surgical/scalpel = 100, \ /obj/item/weapon/material/knife = 75, \ @@ -57,6 +59,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/face/mend_vocal + surgery_name = "Mend Vocal Cords" allowed_tools = list( /obj/item/weapon/surgical/hemostat = 100, \ /obj/item/stack/cable_coil = 75, \ @@ -89,6 +92,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/face/fix_face + surgery_name = "Fix Face" allowed_tools = list( /obj/item/weapon/surgical/retractor = 100, \ /obj/item/weapon/material/kitchen/utensil/fork = 75 @@ -123,6 +127,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/face/cauterize + surgery_name = "Cauterize Face" allowed_tools = list( /obj/item/weapon/surgical/cautery = 100, \ /obj/item/clothing/mask/smokable/cigarette = 75, \ @@ -156,4 +161,4 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message("[user]'s hand slips, leaving a small burn on [target]'s face with \the [tool]!", \ "Your hand slips, leaving a small burn on [target]'s face with \the [tool]!") - target.apply_damage(4, BURN, affected) \ No newline at end of file + target.apply_damage(4, BURN, affected) diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index d26ea6c0c18..8f25b42328e 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -29,6 +29,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/generic/cut_open + surgery_name = "Create Incision" allowed_tools = list( /obj/item/weapon/surgical/scalpel = 100, \ /obj/item/weapon/material/knife = 75, \ @@ -73,16 +74,18 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/generic/cut_with_laser + surgery_name = "Create Bloodless Incision" allowed_tools = list( - /obj/item/weapon/surgical/scalpel/laser3 = 95, \ - /obj/item/weapon/surgical/scalpel/laser2 = 85, \ - /obj/item/weapon/surgical/scalpel/laser1 = 75, \ + /obj/item/weapon/surgical/scalpel/laser3 = 100, \ + /obj/item/weapon/surgical/scalpel/laser2 = 100, \ + /obj/item/weapon/surgical/scalpel/laser1 = 100, \ /obj/item/weapon/melee/energy/sword = 5 ) priority = 2 req_open = 0 min_duration = 90 max_duration = 110 + excludes_steps = list(/datum/surgery_step/generic/cut_open) /datum/surgery_step/generic/cut_with_laser/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) @@ -98,13 +101,25 @@ /datum/surgery_step/generic/cut_with_laser/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 made a bloodless incision on [target]'s [affected.name] with \the [tool].", \ - "You have made a bloodless incision on [target]'s [affected.name] with \the [tool].",) - //Could be cleaner ... affected.open = 1 affected.createwound(CUT, 1) - affected.organ_clamp() + var/clamp_chance = 0 //I hate this. Make all laser scalpels a /laser subtype and give them a clamp_chance var??? + if(istype(tool,/obj/item/weapon/surgical/scalpel/laser1)) + clamp_chance = 75 + if(istype(tool,/obj/item/weapon/surgical/scalpel/laser2)) + clamp_chance = 85 + if(istype(tool,/obj/item/weapon/surgical/scalpel/laser3)) + clamp_chance = 95 + if(clamp_chance) + affected.organ_clamp() + user.visible_message("[user] has made a bloodless incision on [target]'s [affected.name] with \the [tool].", \ + "You have made a bloodless incision on [target]'s [affected.name] with \the [tool].",) + else + user.visible_message("[user] has made an incision on [target]'s [affected.name] with \the [tool], but blood is still escaping from the wound.", \ + "You have made an incision on [target]'s [affected.name] with \the [tool], but blood is still coming from the wound..",) + //Could be cleaner ... + spread_germs_to_organ(affected, user) /datum/surgery_step/generic/cut_with_laser/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -119,6 +134,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/generic/incision_manager + surgery_name = "Create Prepared Incision" allowed_tools = list( /obj/item/weapon/surgical/scalpel/manager = 100 ) @@ -127,6 +143,7 @@ req_open = 0 min_duration = 80 max_duration = 120 + excludes_steps = list(/datum/surgery_step/generic/cut_open) /datum/surgery_step/generic/incision_manager/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(..()) @@ -165,6 +182,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/generic/clamp_bleeders + surgery_name = "Clamp Bleeders" allowed_tools = list( /obj/item/weapon/surgical/hemostat = 100, \ /obj/item/stack/cable_coil = 75, \ @@ -204,6 +222,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/generic/retract_skin + surgery_name = "Retract Skin" allowed_tools = list( /obj/item/weapon/surgical/retractor = 100, \ /obj/item/weapon/material/kitchen/utensil/fork = 50 @@ -264,6 +283,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/generic/cauterize + surgery_name = "Cauterize Incision" allowed_tools = list( /obj/item/weapon/surgical/cautery = 100, \ /obj/item/clothing/mask/smokable/cigarette = 75, \ @@ -305,6 +325,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/generic/amputate + surgery_name = "Amputate Limb" allowed_tools = list( /obj/item/weapon/surgical/circular_saw = 100, \ /obj/item/weapon/material/knife/machete/hatchet = 75 diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 745dc3e8924..c3c2496cfdf 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -5,6 +5,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/cavity + surgery_name = "Cavity" priority = 1 /datum/surgery_step/cavity/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -46,6 +47,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/cavity/make_space + surgery_name = "Create Cavity" allowed_tools = list( /obj/item/weapon/surgical/surgicaldrill = 100, \ /obj/item/weapon/pen = 75, \ @@ -78,6 +80,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/cavity/close_space + surgery_name = "Close Cavity" priority = 2 allowed_tools = list( /obj/item/weapon/surgical/cautery = 100, \ @@ -112,6 +115,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/cavity/place_item + surgery_name = "Implant Object" priority = 0 allowed_tools = list(/obj/item = 100) @@ -175,6 +179,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/cavity/implant_removal + surgery_name = "Remove Implant" allowed_tools = list( /obj/item/weapon/surgical/hemostat = 100, \ /obj/item/weapon/material/kitchen/utensil/fork = 20 @@ -203,49 +208,54 @@ /datum/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) - var/find_prob = 0 - if (affected.implants.len) - var/obj/item/obj = pick(affected.implants) + var/obj/item/obj = tgui_input_list(user, "Which embedded item do you wish to remove?", "Surgery Select", affected.implants) + if(isnull(obj)) //They clicked cancel. + user.visible_message("[user] takes \the [tool] out of [target]'s [affected.name].", \ + "You take \the [tool] out of the incision on [target]'s [affected.name]." ) + return + if(!do_mob(user, target, 1)) //They moved away + to_chat(user, "You must remain close to and keep focused on your patient to conduct surgery.") + user.visible_message("[user] fails to remove anything from [target]'s [affected.name] with \the [tool]!", \ + "You fail to remove the [obj] from [target]'s [affected.name]s with \the [tool]!" ) + return if(istype(obj,/obj/item/weapon/implant)) var/obj/item/weapon/implant/imp = obj - if (imp.islegal()) - find_prob +=60 - else - find_prob +=40 + if (!imp.islegal()) //ILLEGAL IMPLANT ALERT!!!!!!!!!! + user.visible_message("[user] seems to be intently working on something within [target]'s [affected.name] with \the [tool]!", \ + "You intently begin to take [obj] out of the incision on [target]'s [affected.name]s with \the [tool]!" ) + if(!do_after(user, min_duration, target)) + user.visible_message("[user] fails to remove anything from [target]'s [affected.name] with \the [tool]!", \ + "You fail to remove the [obj] from [target]'s [affected.name]s with \the [tool]!" ) + return + + + user.visible_message("[user] takes something out of the incision on [target]'s [affected.name] with \the [tool]!", \ + "You take [obj] out of the incision on [target]'s [affected.name]s with \the [tool]!" ) + affected.implants -= obj + if(!target.has_embedded_objects()) + target.clear_alert("embeddedobject") + + BITSET(target.hud_updateflag, IMPLOYAL_HUD) + + //Handle possessive brain borers. + if(istype(obj,/mob/living/simple_mob/animal/borer)) + var/mob/living/simple_mob/animal/borer/worm = obj + if(worm.controlling) + target.release_control() + worm.detatch() + worm.leave_host() else - find_prob +=50 - - if (prob(find_prob)) - user.visible_message("[user] takes something out of incision on [target]'s [affected.name] with \the [tool]!", \ - "You take [obj] out of incision on [target]'s [affected.name]s with \the [tool]!" ) - affected.implants -= obj - if(!target.has_embedded_objects()) - target.clear_alert("embeddedobject") - - BITSET(target.hud_updateflag, IMPLOYAL_HUD) - - //Handle possessive brain borers. - if(istype(obj,/mob/living/simple_mob/animal/borer)) - var/mob/living/simple_mob/animal/borer/worm = obj - if(worm.controlling) - target.release_control() - worm.detatch() - worm.leave_host() - else - obj.loc = get_turf(target) - obj.add_blood(target) - obj.update_icon() - if(istype(obj,/obj/item/weapon/implant)) - var/obj/item/weapon/implant/imp = obj - imp.imp_in = null - imp.implanted = 0 - else if(istype(tool,/obj/item/device/nif)){var/obj/item/device/nif/N = tool;N.unimplant(target)} //VOREStation Add - NIF support - else - user.visible_message("[user] removes \the [tool] from [target]'s [affected.name].", \ - "There's something inside [target]'s [affected.name], but you just missed it this time." ) + obj.loc = get_turf(target) + obj.add_blood(target) + obj.update_icon() + if(istype(obj,/obj/item/weapon/implant)) + var/obj/item/weapon/implant/imp = obj + imp.imp_in = null + imp.implanted = 0 + else if(istype(tool,/obj/item/device/nif)){var/obj/item/device/nif/N = tool;N.unimplant(target)} //VOREStation Add - NIF support else user.visible_message("[user] could not find anything inside [target]'s [affected.name], and pulls \the [tool] out.", \ "You could not find anything inside [target]'s [affected.name]." ) diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index 8a25be5b510..56c0ccccc15 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/limb/ + surgery_name = "Limb" priority = 3 // Must be higher than /datum/surgery_step/internal req_open = 0 can_infect = 0 @@ -22,6 +23,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/limb/attach + surgery_name = "Attach Limb" allowed_tools = list(/obj/item/organ/external = 100) min_duration = 50 @@ -81,6 +83,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/limb/connect + surgery_name = "Connect Limb" allowed_tools = list( /obj/item/weapon/surgical/hemostat = 100, \ /obj/item/stack/cable_coil = 75, \ @@ -120,6 +123,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/limb/mechanize + surgery_name = "Mechanize Limb" allowed_tools = list(/obj/item/robot_parts = 100) min_duration = 80 diff --git a/code/modules/surgery/neck.dm b/code/modules/surgery/neck.dm index 6b970ad4c2c..5b590756129 100644 --- a/code/modules/surgery/neck.dm +++ b/code/modules/surgery/neck.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////////// /datum/surgery_step/brainstem + surgery_name = "Brainstem" priority = 2 req_open = 1 can_infect = 1 @@ -23,6 +24,7 @@ ///////////////////////////// /datum/surgery_step/brainstem/mend_vessels + surgery_name = "Mend Vessels" priority = 1 allowed_tools = list( /obj/item/weapon/surgical/FixOVein = 100, @@ -57,6 +59,7 @@ ///////////////////////////// /datum/surgery_step/brainstem/drill_vertebrae + surgery_name = "Drill Vertebrae" priority = 3 //Do this instead of expanding the skull cavity allowed_tools = list( /obj/item/weapon/surgical/surgicaldrill = 100, @@ -100,6 +103,7 @@ ///////////////////////////// /datum/surgery_step/brainstem/clean_chips + surgery_name = "Remove Bone Chips" priority = 3 //Do this instead of picking around for implants. allowed_tools = list( /obj/item/weapon/surgical/hemostat = 100, @@ -139,6 +143,7 @@ ///////////////////////////// /datum/surgery_step/brainstem/mend_cord + surgery_name = "Mend Spinal Cord" priority = 1 //Do this after IB. allowed_tools = list( /obj/item/weapon/surgical/FixOVein = 100, @@ -179,6 +184,7 @@ ///////////////////////////// /datum/surgery_step/brainstem/mend_vertebrae + surgery_name = "Mend Vertebrae" priority = 3 //Do this instead of fixing bones. allowed_tools = list( /obj/item/weapon/surgical/bonegel = 100, @@ -217,6 +223,7 @@ ///////////////////////////// /datum/surgery_step/brainstem/realign_tissue + surgery_name = "Realign Tissue" priority = 3 //Do this instead of searching for objects in the skull. allowed_tools = list( /obj/item/weapon/surgical/hemostat = 100, diff --git a/code/modules/surgery/organ_ripper_vr.dm b/code/modules/surgery/organ_ripper_vr.dm new file mode 100644 index 00000000000..0fa8f751c59 --- /dev/null +++ b/code/modules/surgery/organ_ripper_vr.dm @@ -0,0 +1,232 @@ +// Ripper tool. This is only for harming the patient or (in organs_internal.dm) ripping out an organ. +// This means if you want to torture someone, do medical malpractice, or harm a fresh sleeve for teaching medical, you can. + +/datum/surgery_step/generic/ripper //This is the base which should never be seen. + surgery_name = "Ripper Tool" + + priority = 3 + + blood_level = 99 //Ripper sugery gets you super bloody. + + min_duration = 60 + max_duration = 80 + excludes_steps = list(/datum/surgery_step/generic/cut_open) //These things can already do the first step! + +/datum/surgery_step/generic/ripper/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/weapon/surgical/scalpel/ripper/tool) + + if (!..()) + return 0 + + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + if(!istype(tool)) //Only rippers can use the ripper! + return 0 + + if(affected.robotic >= ORGAN_ROBOT) //You can't damage robutts. + return 0 + + return affected && affected.open != 0 && target_zone != O_MOUTH //Have to cut them open at a minimum. + +/datum/surgery_step/generic/ripper/tear_vessel + surgery_name = "Tear Blood Vessel" + allowed_tools = list( + /obj/item/weapon/surgical/scalpel/ripper = 100 + ) + +/datum/surgery_step/generic/ripper/tear_vessel/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user] starts ripping into [target] with \the [tool].", \ + "You start ripping into [target] with \the [tool].") + target.custom_pain("[user] is ripping into your [target.op_stage.current_organ]!", 100) + ..() + +/datum/surgery_step/generic/ripper/tear_vessel/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 ripped [target]'s [affected] \the [tool], blood and viscera spraying everywhere!", \ + "You have ripped [target]'s [target.op_stage.current_organ] out with \the [tool], spraying blood all through the room!") + var/datum/wound/internal_bleeding/I = new (30) //splurt. New severed artery. + affected.wounds += I + affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1) + target.drip(30) //Lose a lot of blood. + new /obj/effect/gibspawner/human(target.loc,target.dna,target.species.flesh_color,target.species.blood_color) //SPLAT. + target.emote("scream") //Hope you put them under... + +/datum/surgery_step/generic/ripper/tear_vessel/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("[user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \ + "Your hand slips, damaging [target]'s [affected.name] with \the [tool]!") + affected.createwound(BRUISE, 20) //Only bruised...Sad. + + +//Break Bone +/datum/surgery_step/generic/ripper/break_bone + surgery_name = "Break Skeletal Structure" + allowed_tools = list( + /obj/item/weapon/surgical/scalpel/ripper = 100 + ) + +/datum/surgery_step/generic/ripper/break_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 violently shifting \the [tool] in [target]'s [affected.name]!", \ + "You start violently moving the [tool] in [target]'s [affected.name]!") + target.custom_pain("[user] is ripping into your [target.op_stage.current_organ]!", 100) + ..() + +/datum/surgery_step/generic/ripper/break_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("[user] has destroyed the bones within [target]'s [affected] with \the [tool]", \ + "You have destroyed the bones in [target]'s [affected] with \the [tool]!") + affected.fracture() + affected.createwound(BRUISE, 20) + target.emote("scream") //Hope you put them under... + +/datum/surgery_step/generic/ripper/tear_vessel/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("[user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \ + "Your hand slips, damaging [target]'s [affected.name] with \the [tool]!") + affected.createwound(BRUISE, 20) + +//Mutilate Organ + +/datum/surgery_step/generic/ripper/destroy_organ + surgery_name = "Mutilate Organ" + allowed_tools = list( + /obj/item/weapon/surgical/scalpel/ripper = 100 + ) + +/datum/surgery_step/generic/ripper/destroy_organ/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!..()) + return 0 + + var/list/removable_organs = list() + for(var/organ in target.internal_organs_by_name) + var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] + if(istype(I) && I.parent_organ == target_zone) + removable_organs |= organ + + if(!removable_organs.len) + return 0 + return ..() + +/datum/surgery_step/generic/ripper/destroy_organ/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) + + var/list/removable_organs = list() + for(var/organ in target.internal_organs_by_name) + var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] + if(istype(I) && I.parent_organ == target_zone) + removable_organs |= organ + + var/organ_to_destroy = tgui_input_list(user, "Which organ do you want to mutilate?", "Organ Choice", removable_organs) + + if(!organ_to_destroy) //They decided to cancel. Let's slowly pull the tool back... + to_chat(user, "You decide against mutilating any organs.") + user.visible_message("[user] starts pulling their [tool] out from [target]'s [affected.name] with \the [tool].", \ + "You start pulling your \the [tool] out of [target]'s [affected.name].") + target.custom_pain("Someone's moving something around in your [affected.name]!", 100) + else if(organ_to_destroy) + target.op_stage.current_organ = organ_to_destroy + user.visible_message("[user] starts ripping into [target]'s [target.op_stage.current_organ] with \the [tool].", \ + "You start ripping [target]'s [target.op_stage.current_organ] with \the [tool].") + target.custom_pain("Someone's ripping out your [target.op_stage.current_organ]!", 100) + ..() + + +/datum/surgery_step/generic/ripper/destroy_organ/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(!target.op_stage.current_organ) + user.visible_message("[user] has pulled their \the [tool] from [target]'s [affected.name].", \ + "You have pulled your [tool] out from [target]'s [affected].") + + // Damage the organ! + if(target.op_stage.current_organ) + user.visible_message("[user] has ripped [target]'s [target.op_stage.current_organ] out with \the [tool].", \ + "You have ripped [target]'s [target.op_stage.current_organ] out with \the [tool].") + var/obj/item/organ/O = target.internal_organs_by_name[target.op_stage.current_organ] + if(O && istype(O)) + O.take_damage(10) + target.op_stage.current_organ = null + new /obj/effect/gibspawner/human(target.loc,target.dna,target.species.flesh_color,target.species.blood_color) + target.emote("scream") + +/datum/surgery_step/generic/ripper/destroy_organ/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("[user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \ + "Your hand slips, damaging [target]'s [affected.name] with \the [tool]!") + affected.createwound(BRUISE, 20) + +/////////////////////////////////////////////////////////////// +// Organ Ripping Surgery +/////////////////////////////////////////////////////////////// + +/datum/surgery_step/generic/ripper/rip_organ + surgery_name = "Rip Out Organ" + + allowed_tools = list( + /obj/item/weapon/surgical/scalpel/ripper = 100 + ) + + priority = 3 + + blood_level = 3 + + min_duration = 60 + max_duration = 80 + excludes_steps = list(/datum/surgery_step/generic/cut_open) + +/datum/surgery_step/generic/ripper/rip_organ/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!..()) + return 0 + + var/list/removable_organs = list() + for(var/organ in target.internal_organs_by_name) + var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] + if(istype(I) && I.parent_organ == target_zone) + removable_organs |= organ + + if(!removable_organs.len) + return 0 + + return ..() + +/datum/surgery_step/generic/ripper/rip_organ/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) + var/list/removable_organs = list() + for(var/organ in target.internal_organs_by_name) + var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] + if(istype(I) && I.parent_organ == target_zone) + removable_organs |= organ + + var/organ_to_remove = tgui_input_list(user, "Which organ do you want to tear out?", "Organ Choice", removable_organs) + if(!organ_to_remove) //They decided to cancel. Let's slowly pull the tool back... + to_chat(user, "You decide against ripping out any organs.") + user.visible_message("[user] starts pulling their [tool] out from [target]'s [affected.name] with \the [tool].", \ + "You start pulling your \the [tool] out of [target]'s [affected.name].") + target.custom_pain("Someone's moving something around in your [affected.name]!", 100) + else if(organ_to_remove) + target.op_stage.current_organ = organ_to_remove + user.visible_message("[user] starts ripping [target]'s [target.op_stage.current_organ] out with \the [tool].", \ + "You start ripping [target]'s [target.op_stage.current_organ] out with \the [tool].") + target.custom_pain("Someone's ripping out your [target.op_stage.current_organ]!", 100) + ..() + +/datum/surgery_step/generic/ripper/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(!target.op_stage.current_organ) + user.visible_message("[user] has pulled their \the [tool] from [target]'s [affected.name].", \ + "You have pulled your [tool] out from [target]'s [affected].") + + if(target.op_stage.current_organ) + user.visible_message("[user] has ripped [target]'s [target.op_stage.current_organ] out with \the [tool].", \ + "You have ripped [target]'s [target.op_stage.current_organ] out with \the [tool].") + var/obj/item/organ/O = target.internal_organs_by_name[target.op_stage.current_organ] + if(O && istype(O)) + O.removed(user) + target.op_stage.current_organ = null + new /obj/effect/gibspawner/human(target.loc,target.dna,target.species.flesh_color,target.species.blood_color) + target.emote("scream") + +/datum/surgery_step/internal/rip_organ/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("[user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \ + "Your hand slips, damaging [target]'s [affected.name] with \the [tool]!") + affected.createwound(BRUISE, 20) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index e5f49cc922f..e92010f8d38 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -78,6 +78,8 @@ if(!(I.robotic >= ORGAN_ROBOT)) user.visible_message("[user] treats damage to [target]'s [I.name] with [tool_name].", \ "You treat damage to [target]'s [I.name] with [tool_name]." ) + if(I.organ_tag == O_BRAIN && I.status == ORGAN_DEAD && target.can_defib == 0) //Let people know they still got more work to get the brain back into working order. + to_chat(user, "You fix their [I] but the neurological structure is still heavily damaged and in need of repair.") I.damage = 0 I.status = 0 if(I.organ_tag == O_EYES) @@ -105,6 +107,81 @@ if(I && I.damage > 0) I.take_damage(dam_amt,0) + + + + + +//Robo internal organ fix. For when an organic has robotic limbs. +/datum/surgery_step/fix_organic_organ_robotic //For artificial organs + allowed_tools = list( + /obj/item/stack/nanopaste = 100, + /obj/item/stack/cable_coil = 75, + /obj/item/weapon/tool/wrench = 50, + /obj/item/weapon/storage/toolbox = 10 //Percussive Maintenance + ) + + min_duration = 70 + max_duration = 90 + +/datum/surgery_step/fix_organic_organ_robotic/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) return + var/is_organ_damaged = 0 + for(var/obj/item/organ/I in affected.internal_organs) + if(I.damage > 0 && (I.robotic >= ORGAN_ROBOT)) + is_organ_damaged = 1 + break + return affected.open != 3 && is_organ_damaged //Robots have their own code. + +/datum/surgery_step/fix_organic_organ_robotic/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + for(var/obj/item/organ/I in affected.internal_organs) + if(I && I.damage > 0) + if(I.robotic >= ORGAN_ROBOT) + user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ + "You start mending the damage to [target]'s [I.name]'s mechanisms." ) + + target.custom_pain("The pain in your [affected.name] is living hell!",1) + ..() + +/datum/surgery_step/fix_organic_organ_robotic/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + for(var/obj/item/organ/I in affected.internal_organs) + if(I && I.damage > 0) + if(I.robotic >= ORGAN_ROBOT) + user.visible_message("[user] repairs [target]'s [I.name] with [tool].", \ + "You repair [target]'s [I.name] with [tool]." ) + I.damage = 0 + if(I.organ_tag == O_EYES) + target.sdisabilities &= ~BLIND + +/datum/surgery_step/fix_organic_organ_robotic/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + + user.visible_message("[user]'s hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!", \ + "Your hand slips, gumming up the mechanisms inside of [target]'s [affected.name] with \the [tool]!") + + target.adjustBruteLoss(5) + + for(var/obj/item/organ/I in affected.internal_organs) + if(I) + I.take_damage(rand(3,5),0) + + +//Robo limb fix end + + /////////////////////////////////////////////////////////////// // Organ Detaching Surgery /////////////////////////////////////////////////////////////// @@ -175,13 +252,14 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/internal/remove_organ + surgery_name = "Remove Organ" allowed_tools = list( /obj/item/weapon/surgical/hemostat = 100, \ /obj/item/weapon/material/kitchen/utensil/fork = 20 ) - allowed_procs = list(IS_WIRECUTTER = 75) + allowed_procs = list(IS_WIRECUTTER = 100) //FBP code also uses this, so let's be nice. Roboticists won't know to use hemostats. min_duration = 60 max_duration = 80 @@ -193,8 +271,19 @@ if(!istype(tool)) return 0 - target.op_stage.current_organ = null + var/list/removable_organs = list() + for(var/organ in target.internal_organs_by_name) + var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] + if(istype(I) && (I.status & ORGAN_CUT_AWAY) && I.parent_organ == target_zone) + removable_organs |= organ + if(!removable_organs.len) + return 0 + + return ..() + +/datum/surgery_step/internal/remove_organ/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) var/list/removable_organs = list() for(var/organ in target.internal_organs_by_name) var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] @@ -202,28 +291,32 @@ removable_organs |= organ var/organ_to_remove = tgui_input_list(user, "Which organ do you want to remove?", "Organ Choice", removable_organs) - if(!organ_to_remove) - return 0 + if(!organ_to_remove) //They chose cancel! + to_chat(user, "You decide against preparing any organs for removal.") + user.visible_message("[user] starts pulling \the [tool] from [target]'s [affected]", \ + "You start pulling \the [tool] from [target]'s [affected].") target.op_stage.current_organ = organ_to_remove - return ..() -/datum/surgery_step/internal/remove_organ/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] starts removing [target]'s [target.op_stage.current_organ] with \the [tool].", \ "You start removing [target]'s [target.op_stage.current_organ] with \the [tool].") target.custom_pain("Someone's ripping out your [target.op_stage.current_organ]!", 100) ..() /datum/surgery_step/internal/remove_organ/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] has removed [target]'s [target.op_stage.current_organ] with \the [tool].", \ - "You have removed [target]'s [target.op_stage.current_organ] with \the [tool].") + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!target.op_stage.current_organ) //They chose to remove their tool instead. + user.visible_message("[user] has removed \the [tool] from [target]'s [affected].", \ + "You have removed \the [tool] from [target]'s [affected].") // Extract the organ! if(target.op_stage.current_organ) + user.visible_message("[user] has removed [target]'s [target.op_stage.current_organ] with \the [tool].", \ + "You have removed [target]'s [target.op_stage.current_organ] with \the [tool].") var/obj/item/organ/O = target.internal_organs_by_name[target.op_stage.current_organ] if(O && istype(O)) O.removed(user) - target.op_stage.current_organ = null + target.op_stage.current_organ = null /datum/surgery_step/internal/remove_organ/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) @@ -364,65 +457,3 @@ user.visible_message("[user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!", \ "Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!") affected.createwound(BRUISE, 20) - -/////////////////////////////////////////////////////////////// -// Organ Ripping Surgery -/////////////////////////////////////////////////////////////// - -/datum/surgery_step/internal/rip_organ - - allowed_tools = list( - /obj/item/weapon/surgical/scalpel/ripper = 100 - ) - - priority = 3 - - blood_level = 3 - - min_duration = 60 - max_duration = 80 - -/datum/surgery_step/internal/rip_organ/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!..()) - return 0 - - if(!istype(tool)) - return 0 - - target.op_stage.current_organ = null - - var/list/removable_organs = list() - for(var/organ in target.internal_organs_by_name) - var/obj/item/organ/internal/I = target.internal_organs_by_name[organ] - if(istype(I) && I.parent_organ == target_zone) - removable_organs |= organ - - var/organ_to_remove = tgui_input_list(user, "Which organ do you want to remove?", "Organ Choice", removable_organs) - if(!organ_to_remove) - return 0 - - target.op_stage.current_organ = organ_to_remove - return ..() - -/datum/surgery_step/internal/rip_organ/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts ripping [target]'s [target.op_stage.current_organ] out with \the [tool].", \ - "You start ripping [target]'s [target.op_stage.current_organ] out with \the [tool].") - target.custom_pain("Someone's ripping out your [target.op_stage.current_organ]!", 100) - ..() - -/datum/surgery_step/internal/rip_organ/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] has ripped [target]'s [target.op_stage.current_organ] out with \the [tool].", \ - "You have ripped [target]'s [target.op_stage.current_organ] out with \the [tool].") - - // Extract the organ! - if(target.op_stage.current_organ) - var/obj/item/organ/O = target.internal_organs_by_name[target.op_stage.current_organ] - if(O && istype(O)) - O.removed(user) - target.op_stage.current_organ = null - -/datum/surgery_step/internal/rip_organ/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("[user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \ - "Your hand slips, damaging [target]'s [affected.name] with \the [tool]!") - affected.createwound(BRUISE, 20) diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 9cde26f240f..c0c081e05b8 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/fix_vein + surgery_name = "Fix Vein" priority = 2 allowed_tools = list( /obj/item/weapon/surgical/FixOVein = 100, \ @@ -61,6 +62,7 @@ // Necrosis Surgery Step 1 /////////////////////////////////////////////////////////////// /datum/surgery_step/fix_dead_tissue //Debridement + surgery_name = "Remove Dead Tissue" priority = 2 allowed_tools = list( /obj/item/weapon/surgical/scalpel = 100, \ @@ -110,6 +112,7 @@ // Necrosis Surgery Step 2 /////////////////////////////////////////////////////////////// /datum/surgery_step/treat_necrosis + surgery_name = "Treat Necrosis" priority = 2 allowed_tools = list( /obj/item/weapon/reagent_containers/dropper = 100, @@ -187,6 +190,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/hardsuit + surgery_name = "Remove Hardsuit" allowed_tools = list( /obj/item/weapon/weldingtool = 80, /obj/item/weapon/surgical/circular_saw = 60, @@ -241,6 +245,7 @@ var/dehusk = 0 /datum/surgery_step/dehusk/ + surgery_name = "Dehusk" priority = 1 can_infect = 0 blood_level = 1 @@ -256,6 +261,7 @@ return target_zone == BP_TORSO && (HUSK in target.mutations) /datum/surgery_step/dehusk/structinitial + surgery_name = "Create Structure" allowed_tools = list( /obj/item/weapon/surgical/bioregen = 100 ) @@ -285,6 +291,7 @@ ..() /datum/surgery_step/dehusk/relocateflesh + surgery_name = "Relocate Flesh" allowed_tools = list( /obj/item/weapon/surgical/hemostat = 100, \ /obj/item/stack/cable_coil = 75, \ @@ -316,6 +323,7 @@ ..() /datum/surgery_step/dehusk/structfinish + surgery_name = "Finish Structure" allowed_tools = list( /obj/item/weapon/surgical/bioregen = 100, \ /obj/item/weapon/surgical/FixOVein = 30 @@ -357,6 +365,7 @@ ..() /datum/surgery_step/internal/detoxify + surgery_name = "Detoxify" blood_level = 1 allowed_tools = list(/obj/item/weapon/surgical/bioregen=100) min_duration = 90 @@ -385,4 +394,4 @@ "Your hand slips, failing to finish the surgery, and damaging [target] with \the [tool].") affected.createwound(CUT, 15) affected.createwound(BRUISE, 10) - ..() \ No newline at end of file + ..() diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index b424852ad91..f28ccfaf7f7 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -4,6 +4,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/ + surgery_name = "Robotic Surgery" can_infect = 0 /datum/surgery_step/robotics/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) @@ -29,6 +30,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/unscrew_hatch + surgery_name = "Unscrew Hatch" allowed_tools = list( /obj/item/weapon/coin = 50, /obj/item/weapon/material/knife = 50 @@ -68,6 +70,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/open_hatch + surgery_name = "Open Hatch" allowed_tools = list( /obj/item/weapon/surgical/retractor = 100, /obj/item/weapon/material/kitchen/utensil = 50 @@ -105,6 +108,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/close_hatch + surgery_name = "Close Hatch" allowed_tools = list( /obj/item/weapon/surgical/retractor = 100, /obj/item/weapon/material/kitchen/utensil = 50 @@ -143,6 +147,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/repair_brute + surgery_name = "Repair Robotic Brute" allowed_tools = list( /obj/item/weapon/weldingtool = 100, /obj/item/weapon/pickaxe/plasmacutter = 50 @@ -184,6 +189,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/repair_burn + surgery_name = "Repair Robotic Burn" allowed_tools = list( /obj/item/stack/cable_coil = 100 ) @@ -232,6 +238,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/fix_organ_robotic //For artificial organs + surgery_name = "Fix Robotic Organ" allowed_tools = list( /obj/item/stack/nanopaste = 100, \ /obj/item/weapon/surgical/bonegel = 30, \ @@ -302,7 +309,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/detatch_organ_robotic - + surgery_name = "Detach Robotic Organ" allowed_tools = list( /obj/item/device/multitool = 100 ) @@ -317,23 +324,31 @@ if(affected.open < 3) return 0 - target.op_stage.current_organ = null + var/list/attached_organs = list() //Let's see if we have any organs able to be detached! + 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/list/attached_organs = list() + if(!attached_organs.len) //No organs able to be detached! + return 0 + + return ..() + +/datum/surgery_step/robotics/detatch_organ_robotic/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/list/attached_organs = list() //Which organs can we detach? 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?", "Organ Choice", attached_organs) - if(!organ_to_remove) - return 0 + if(!organ_to_remove) //They chose cancel! + to_chat(user, "You decide against preparing any organs for removal.") + return target.op_stage.current_organ = organ_to_remove - return ..() && organ_to_remove - -/datum/surgery_step/robotics/detatch_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].", \ "You start to decouple [target]'s [target.op_stage.current_organ] with \the [tool]." ) ..() @@ -345,6 +360,7 @@ var/obj/item/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status |= ORGAN_CUT_AWAY + target.op_stage.current_organ = null /datum/surgery_step/robotics/detatch_organ_robotic/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user]'s hand slips, disconnecting \the [tool].", \ @@ -355,6 +371,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/attach_organ_robotic + surgery_name = "Attach Robotic Organ" allowed_procs = list(IS_SCREWDRIVER = 100) min_duration = 100 @@ -367,22 +384,33 @@ if(affected.open < 3) return 0 - target.op_stage.current_organ = null - - var/list/removable_organs = list() + var/list/attachable_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.robotic >= ORGAN_ROBOT) && I.parent_organ == target_zone) - removable_organs |= organ + attachable_organs |= organ - var/organ_to_replace = tgui_input_list(user, "Which organ do you want to reattach?", "Organ Choice", removable_organs) - if(!organ_to_replace) + if(!attachable_organs.len) return 0 - target.op_stage.current_organ = organ_to_replace return ..() /datum/surgery_step/robotics/attach_organ_robotic/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + var/list/attachable_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.robotic >= ORGAN_ROBOT) && I.parent_organ == target_zone) + attachable_organs |= organ + + var/organ_to_replace = tgui_input_list(user, "Which organ do you want to reattach?", "Organ Choice", attachable_organs) + if(!organ_to_replace) //They chose cancel! + to_chat(user, "You decide against reattaching any organs.") + return + + + target.op_stage.current_organ = organ_to_replace + user.visible_message("[user] begins reattaching [target]'s [target.op_stage.current_organ] with \the [tool].", \ "You start reattaching [target]'s [target.op_stage.current_organ] with \the [tool].") ..() @@ -394,6 +422,7 @@ var/obj/item/organ/I = target.internal_organs_by_name[target.op_stage.current_organ] if(I && istype(I)) I.status &= ~ORGAN_CUT_AWAY + target.op_stage.current_organ = null /datum/surgery_step/robotics/attach_organ_robotic/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user]'s hand slips, disconnecting \the [tool].", \ @@ -404,6 +433,7 @@ /////////////////////////////////////////////////////////////// /datum/surgery_step/robotics/install_mmi + surgery_name = "Install MMI" allowed_tools = list( /obj/item/device/mmi = 100 ) @@ -475,9 +505,11 @@ if(clean_name) var/okay = tgui_alert(target,"New name will be '[clean_name]', ok?", "Confirmation",list("Cancel","Ok")) if(okay == "Ok") - target.name = new_name - target.real_name = target.name - return + new_name = clean_name + + new_name = sanitizeName(new_name, allow_numbers = TRUE) + target.name = new_name + target.real_name = target.name /datum/surgery_step/robotics/install_mmi/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user]'s hand slips.", \ @@ -488,6 +520,7 @@ */ /datum/surgery_step/robotics/install_nymph + surgery_name = "Install Nymph" allowed_tools = list( /obj/item/weapon/holder/diona = 100 ) diff --git a/code/modules/surgery/slimes.dm b/code/modules/surgery/slimes.dm index e73633397a0..84d697272ce 100644 --- a/code/modules/surgery/slimes.dm +++ b/code/modules/surgery/slimes.dm @@ -3,6 +3,7 @@ ////////////////////////////////////////////////////////////////// /datum/surgery_step/slime + surgery_name = "Slime Surgery" is_valid_target(mob/living/simple_mob/slime/target) return istype(target, /mob/living/simple_mob/slime/) @@ -12,6 +13,7 @@ /datum/surgery_step/slime/cut_flesh + surgery_name = "Cut Flesh" allowed_tools = list( /obj/item/weapon/surgical/scalpel = 100, \ /obj/item/weapon/material/knife = 75, \ @@ -40,6 +42,7 @@ /datum/surgery_step/slime/cut_innards + surgery_name = "Cut Innards" allowed_tools = list( /obj/item/weapon/surgical/scalpel = 100, \ /obj/item/weapon/material/knife = 75, \ @@ -68,6 +71,7 @@ /datum/surgery_step/slime/saw_core + surgery_name = "Remove Core" allowed_tools = list( /obj/item/weapon/surgical/circular_saw = 100, \ /obj/item/weapon/material/knife/machete/hatchet = 75 @@ -97,4 +101,4 @@ /datum/surgery_step/slime/saw_core/fail_step(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) var/datum/gender/T = gender_datums[user.get_visible_gender()] user.visible_message("[user]'s hand slips, causing [T.him] to miss the core!", \ - "Your hand slips, causing you to miss the core!") \ No newline at end of file + "Your hand slips, causing you to miss the core!") diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 24806225c88..ee3e3e19637 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -24,8 +24,13 @@ // evil infection stuff that will make everyone hate me var/can_infect = 0 - //How much blood this step can get on surgeon. 1 - hands, 2 - full body. + // How much blood this step can get on surgeon. 1 - hands, 2 - full body. var/blood_level = 0 + // What the surgery will be called in the rare event of multiple surgery steps being shown to the user. + var/surgery_name = "CONTACT A DEVELOPER TO NAME THIS STEP." + // If the surgery stops you from being able to perform another surgery. + var/list/excludes_steps = list() + //returns how well tool is suited for this step /datum/surgery_step/proc/tool_quality(obj/item/tool) @@ -134,57 +139,90 @@ if(!istype(M)) return 0 if (user.a_intent == I_HURT) //check for Hippocratic Oath + //Insert intentional hurt medical code here. return 0 var/zone = user.zone_sel.selecting if(zone in M.op_stage.in_progress) //Can't operate on someone repeatedly. to_chat(user, "You can't operate on this area while surgery is already in progress.") return 1 + var/obj/surface = M.get_surgery_surface(user) + if(!surface || !surface.surgery_odds) // If the surface has a chance of 0% surgery odds (ground), don't even bother trying to do surgery. + return 0 // This is meant to prevent the 'glass shard mouth 60 damage click' exploit. Also saves CPU by doing it here! + var/list/datum/surgery_step/available_surgeries = list() for(var/datum/surgery_step/S in surgery_steps) //check if tool is right or close enough and if this step is possible if(S.tool_quality(src)) var/step_is_valid = S.can_use(user, M, zone, src) if(step_is_valid && S.is_valid_target(M)) + if(step_is_valid == SURGERY_FAILURE) + continue + available_surgeries[S.surgery_name] = S //Adds the surgery name to the list and sets it equal to S. (Ex: "Cauterize" = surgery_step/cauterize) + continue - if(M == user) // Once we determine if we can actually do a step at all, give a slight delay to self-surgery to confirm attempts. - to_chat(user, "You focus on attempting to perform surgery upon yourself.") + if(!available_surgeries.len) //No available surgeries. Failure. + return 0 - if(!do_after(user, 3 SECONDS, M)) - return 0 + // Having trouble with an ASSOSCIATED LIST? or REMOVING SOMETHING FROM AN ASSOCIATED LIST? Look here for a quick guide, developed out of frustration. + // Note: This is an ultra edge case. Like, what is being done here is horrible and is so rare this should never happen again in the code. + // This block of code caused hours of suffering. - if(step_is_valid == SURGERY_FAILURE) // This is a failure that already has a message for failing. - return 1 - M.op_stage.in_progress += zone - S.begin_step(user, M, zone, src) //start on it - var/success = TRUE + for(var/surgical_check_name in available_surgeries) // Get the name from available_surgeries. available_surgeries = list("NAME" = DATUM) + var/datum/surgery_step/surgical_check = available_surgeries[surgical_check_name] // We then get the datum. + if(isnull(surgical_check)) // This is here so it doesn't try to keep searching if the thing we're about to check has been deleted. + continue + if(surgical_check.excludes_steps.len) // We check for it's 'excluded_steps' list and see if it has anything in it. + for(var/removal_candidate_name in available_surgeries) // We then look in available_surgeries once again, grabbing the name. + var/datum/surgery_step/removal_candidate = available_surgeries[removal_candidate_name] // We then get the datum while searching. + if(is_path_in_list(removal_candidate.type, surgical_check.excludes_steps)) // We then check the datum and see if it's a path in the list that we want to remove. + available_surgeries -= removal_candidate_name // We then, finally, remove the surgery step. + // All of this just to make it so you are forced to do bloodless surgery with a laser scalpel. - // Bad tools make it less likely to succeed. - if(!prob(S.tool_quality(src))) - success = FALSE + if(M == user) // Once we determine if we can actually do a step at all, give a slight delay to self-surgery to confirm attempts. + to_chat(user, "You focus on attempting to perform surgery upon yourself.") + if(!do_after(user, 3 SECONDS, M)) + return 0 - // Bad or no surface may mean failure as well. - var/obj/surface = M.get_surgery_surface(user) - if(!surface || !prob(surface.surgery_odds)) - success = FALSE + var/datum/surgery_step/selected_surgery + if(available_surgeries.len > 1) //More than one possible? Ask them which one. + selected_surgery = tgui_input_list(user, "Select which surgery step you wish to perform", "Surgery Select", available_surgeries) //Shows the name in the list. + else + selected_surgery = pick(available_surgeries) - // Not staying still fails you too. - if(success) - var/calc_duration = rand(S.min_duration, S.max_duration) - if(!do_mob(user, M, calc_duration * toolspeed, zone, exclusive = TRUE)) - success = FALSE - to_chat(user, "You must remain close to and keep focused on your patient to conduct surgery.") + if(isnull(selected_surgery)) //They clicked 'cancel' + return 1 + selected_surgery = available_surgeries[selected_surgery] //Sets the name they selected to be the datum. - if(success) - S.end_step(user, M, zone, src) - else - S.fail_step(user, M, zone, src) + M.op_stage.in_progress += zone + selected_surgery.begin_step(user, M, zone, src) //start on it + var/success = TRUE - M.op_stage.in_progress -= zone // Clear the in-progress flag. - if (ishuman(M)) - var/mob/living/carbon/human/H = M - H.update_surgery() - return 1 //don't want to do weapony things after surgery - return 0 + // Bad tools make it less likely to succeed. + if(!prob(selected_surgery.tool_quality(src))) + success = FALSE + + // Bad surface may mean failure as well. + if(!prob(surface.surgery_odds)) + success = FALSE + + // Not staying still fails you too. + if(success) + var/calc_duration = rand(selected_surgery.min_duration, selected_surgery.max_duration) + if(!do_mob(user, M, calc_duration * toolspeed, zone, exclusive = TRUE)) + success = FALSE + to_chat(user, "You must remain close to and keep focused on your patient to conduct surgery.") + + if(success) + selected_surgery.end_step(user, M, zone, src) + else + selected_surgery.fail_step(user, M, zone, src) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) //Gets rid of instakill mechanics. + + M.op_stage.in_progress -= zone // Clear the in-progress flag. + if (ishuman(M)) + var/mob/living/carbon/human/H = M + H.update_surgery() + return 1 //don't want to do weapony things after surgery /proc/sort_surgeries() var/gap = surgery_steps.len @@ -208,4 +246,4 @@ var/brainstem = 0 var/head_reattach = 0 var/current_organ = "organ" - var/list/in_progress = list() \ No newline at end of file + var/list/in_progress = list() diff --git a/vorestation.dme b/vorestation.dme index ab1148ac602..ca379142729 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -3887,6 +3887,7 @@ #include "code\modules\surgery\implant.dm" #include "code\modules\surgery\limb_reattach.dm" #include "code\modules\surgery\neck.dm" +#include "code\modules\surgery\organ_ripper_vr.dm" #include "code\modules\surgery\organs_internal.dm" #include "code\modules\surgery\other.dm" #include "code\modules\surgery\robotics.dm"