From 7534d2109337a2156a336e069df1fdfd0fa374d0 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 11 Oct 2023 11:30:28 +0300 Subject: [PATCH 01/37] make surgery_steps variable a GLOB --- code/_helpers/global_access.dm | 5 ----- code/_helpers/global_lists.dm | 12 +++++++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/code/_helpers/global_access.dm b/code/_helpers/global_access.dm index 753a6d8ab03..f3261b6f990 100644 --- a/code/_helpers/global_access.dm +++ b/code/_helpers/global_access.dm @@ -741,8 +741,6 @@ return global.supply_drop; if("supply_methods_") return global.supply_methods_; - if("surgery_steps") - return global.surgery_steps; if("swapmaps_byname") return global.swapmaps_byname; if("swapmaps_compiled_maxx") @@ -1596,8 +1594,6 @@ global.supply_drop=newval; if("supply_methods_") global.supply_methods_=newval; - if("surgery_steps") - global.surgery_steps=newval; if("swapmaps_byname") global.swapmaps_byname=newval; if("swapmaps_compiled_maxx") @@ -2112,7 +2108,6 @@ "string_slot_flags", "supply_drop", "supply_methods_", - "surgery_steps", "swapmaps_byname", "swapmaps_compiled_maxx", "swapmaps_compiled_maxy", diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 93be0c42d13..18ee24f8c9c 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -5,7 +5,6 @@ GLOBAL_LIST_EMPTY(landmarks_list) // List of all landmarks created. var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions -var/global/list/surgery_steps = list() //list of all surgery steps |BS12 var/global/list/side_effects = list() //list of all medical sideeffects types by thier names |BS12 var/global/list/mechas_list = list() //list of all mechs. Used by hostile mobs target tracking. var/global/list/joblist = list() //list of all jobstypes, minus borg and AI @@ -43,6 +42,9 @@ var/global/list/all_grabobjects[0] // Uplinks var/list/obj/item/device/uplink/world_uplinks = list() +// Surgery steps +GLOBAL_LIST_EMPTY(surgery_steps) + //Preferences stuff //Hairstyles GLOBAL_LIST_EMPTY(hair_styles_list) //stores /datum/sprite_accessory/hair indexed by name @@ -185,10 +187,10 @@ var/global/list/string_slot_flags = list( GLOB.body_marking_styles_list[M.name] = M //Surgery Steps - Initialize all /datum/surgery_step into a list - paths = typesof(/datum/surgery_step)-/datum/surgery_step - for(var/T in paths) - var/datum/surgery_step/S = new T - surgery_steps += S + paths = typesof(/datum/surgery_step) - /datum/surgery_step + for(var/path in paths) + var/datum/surgery_step/S = new path() + GLOB.surgery_steps += S sort_surgeries() //List of job. I can't believe this was calculated multiple times per tick! From f027e325b4a4ab3fb5c30941d4d4ac387afd5fad Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 11 Oct 2023 11:39:13 +0300 Subject: [PATCH 02/37] disable old & enable new surgery_step --- baystation12.dme | 18 +--- code/_helpers/surgery.dm | 45 +++++++++ code/_helpers/unsorted.dm | 24 ----- code/_onclick/item_attack.dm | 8 +- code/datums/surgery/_defines.dm | 23 +++++ code/datums/surgery/surgery_item.dm | 17 ++++ code/datums/surgery/surgery_status.dm | 18 ++++ code/datums/surgery/surgery_step.dm | 138 ++++++++++++++++++++++++++ 8 files changed, 251 insertions(+), 40 deletions(-) create mode 100644 code/_helpers/surgery.dm create mode 100644 code/datums/surgery/_defines.dm create mode 100644 code/datums/surgery/surgery_item.dm create mode 100644 code/datums/surgery/surgery_status.dm create mode 100644 code/datums/surgery/surgery_step.dm diff --git a/baystation12.dme b/baystation12.dme index a5849c2e91e..305b9635bdd 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -153,6 +153,7 @@ #include "code\_helpers\spawn_sync.dm" #include "code\_helpers\sql.dm" #include "code\_helpers\storage.dm" +#include "code\_helpers\surgery.dm" #include "code\_helpers\text.dm" #include "code\_helpers\text_processor.dm" #include "code\_helpers\text_sql_encoding.dm" @@ -450,6 +451,10 @@ #include "code\datums\supplypacks\security.dm" #include "code\datums\supplypacks\supply.dm" #include "code\datums\supplypacks\supplypack.dm" +#include "code\datums\surgery\_defines.dm" +#include "code\datums\surgery\surgery_item.dm" +#include "code\datums\surgery\surgery_status.dm" +#include "code\datums\surgery\surgery_step.dm" #include "code\datums\trading\_trading_defines.dm" #include "code\datums\trading\ai.dm" #include "code\datums\trading\armor.dm" @@ -2801,19 +2806,6 @@ #include "code\modules\splash_text\splash_text.dm" #include "code\modules\supermatter\setup_supermatter.dm" #include "code\modules\supermatter\supermatter.dm" -#include "code\modules\surgery\_defines.dm" -#include "code\modules\surgery\bones.dm" -#include "code\modules\surgery\encased.dm" -#include "code\modules\surgery\face.dm" -#include "code\modules\surgery\generic.dm" -#include "code\modules\surgery\implant.dm" -#include "code\modules\surgery\limb_reattach.dm" -#include "code\modules\surgery\metroids.dm" -#include "code\modules\surgery\organs_internal.dm" -#include "code\modules\surgery\other.dm" -#include "code\modules\surgery\robotics.dm" -#include "code\modules\surgery\surgery.dm" -#include "code\modules\surgery\~defines.dm" #include "code\modules\synthesized_instruments\echo_editor.dm" #include "code\modules\synthesized_instruments\env_editor.dm" #include "code\modules\synthesized_instruments\event_manager.dm" diff --git a/code/_helpers/surgery.dm b/code/_helpers/surgery.dm new file mode 100644 index 00000000000..82273874c93 --- /dev/null +++ b/code/_helpers/surgery.dm @@ -0,0 +1,45 @@ +/proc/sort_surgeries() + var/gap = length(GLOB.surgery_steps) + var/swapped = 1 + while (gap > 1 || swapped) + swapped = 0 + if(gap > 1) + gap = round(gap / 1.247330950103979) + if(gap < 1) + gap = 1 + for(var/i = 1; gap + i <= length(GLOB.surgery_steps); i++) + var/datum/surgery_step/l = GLOB.surgery_steps[i] //Fucking hate + var/datum/surgery_step/r = GLOB.surgery_steps[gap+i] //how lists work here + if(l.priority < r.priority) + GLOB.surgery_steps.Swap(i, gap + i) + swapped = 1 + +//check if mob is lying down on something we can operate him on. +/proc/can_operate(mob/living/carbon/M, mob/living/carbon/user) + var/turf/T = get_turf(M) + if(locate(/obj/machinery/optable, T)) + . = TRUE + if(locate(/obj/structure/bed, T)) + . = TRUE + if(locate(/obj/structure/table, T)) + . = TRUE + if(locate(/obj/effect/rune/, T)) + . = TRUE + + if(M == user) + var/hitzone = check_zone(user.zone_sel.selecting) + var/list/badzones = list(BP_HEAD) + if(user.hand) + badzones += BP_L_ARM + badzones += BP_L_HAND + else + badzones += BP_R_ARM + badzones += BP_R_HAND + if(hitzone in badzones) + return FALSE + +/proc/agjust_organ_image(obj/item/organ/O) + var/image/I = image(icon = O.icon, icon_state = O.icon_state) + I.overlays = O.overlays + I.pixel_y = -5 + return I diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 21965c85b96..691d9e11bba 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -945,30 +945,6 @@ var/global/list/common_tools = list( /obj/item/clothing/mask/smokable/cigarette/can_puncture() return lit -//check if mob is lying down on something we can operate him on. -/proc/can_operate(mob/living/carbon/M, mob/living/carbon/user) - var/turf/T = get_turf(M) - if(locate(/obj/machinery/optable, T)) - . = TRUE - if(locate(/obj/structure/bed, T)) - . = TRUE - if(locate(/obj/structure/table, T)) - . = TRUE - if(locate(/obj/effect/rune/, T)) - . = TRUE - - if(M == user) - var/hitzone = check_zone(user.zone_sel.selecting) - var/list/badzones = list(BP_HEAD) - if(user.hand) - badzones += BP_L_ARM - badzones += BP_L_HAND - else - badzones += BP_R_ARM - badzones += BP_R_HAND - if(hitzone in badzones) - return FALSE - /proc/reverse_direction(dir) switch(dir) if(NORTH) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 43e521e7207..12d39adae99 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -140,9 +140,11 @@ avoid code duplication. This includes items that may sometimes act as a standard /mob/living/attackby(obj/item/I, mob/user) if(!ismob(user)) - return 0 - if(can_operate(src, user) && I.do_surgery(src, user)) //Surgery - return 1 + return FALSE + + if(can_operate(src, user) && I.do_surgery(src, user)) + return TRUE + return I.attack(src, user, user.zone_sel.selecting) /mob/living/carbon/human/attackby(obj/item/I, mob/user) diff --git a/code/datums/surgery/_defines.dm b/code/datums/surgery/_defines.dm new file mode 100644 index 00000000000..b40bfe993dd --- /dev/null +++ b/code/datums/surgery/_defines.dm @@ -0,0 +1,23 @@ +/// Causes hands to become bloody. +#define BLOODY_HANDS (1 << 0) +/// Causes body to become bloody. +#define BLOODY_BODY (1 << 1) + +/// Delta multiplier for all surgeries, ranges from 0.9 to 1.1. +#define SURGERY_DURATION_DELTA rand(9, 11) / 10 + +#define SURGERY_FAILURE -1 +#define SURGERY_BLOCKED -2 + +#define CUT_DURATION 30 +#define AMPUTATION_DURATION 125 +#define CLAMP_DURATION 35 +#define RETRACT_DURATION 25 +#define CAUTERIZE_DURATION 35 +#define GLUE_BONE_DURATION 35 +#define BONE_MEND_DURATION 40 +#define SAW_DURATION 50 +#define DRILL_DURATION 70 +#define ATTACH_DURATION 50 +#define ORGAN_FIX_DURATION 35 +#define CONNECT_DURATION 50 diff --git a/code/datums/surgery/surgery_item.dm b/code/datums/surgery/surgery_item.dm new file mode 100644 index 00000000000..a477a625e54 --- /dev/null +++ b/code/datums/surgery/surgery_item.dm @@ -0,0 +1,17 @@ +/obj/item/proc/do_surgery(mob/living/carbon/target, mob/living/user) + if (!istype(target)) + return FALSE + + if (user.a_intent == I_HURT) + return FALSE + + var/zone = user.zone_sel.selecting + if(zone in target.surgery_status.ongoing_steps) + to_chat(user, SPAN("warning", "You can't operate on this area while surgery is already in progress.")) + return TRUE + + for(var/datum/surgery_step/S in GLOB.surgery_steps) + if(S.do_step(user, target, src, zone)) + return TRUE + + return FALSE diff --git a/code/datums/surgery/surgery_status.dm b/code/datums/surgery/surgery_status.dm new file mode 100644 index 00000000000..e8d72abb8ad --- /dev/null +++ b/code/datums/surgery/surgery_status.dm @@ -0,0 +1,18 @@ +/datum/surgery_status + /** + * List of zones where surgery steps are currently performed. + */ + var/list/ongoing_steps = list() + /** + * Associative list of string -> type, where string is zone name and + * type is a reference to an operated organ. + */ + var/list/operated_organs = list() + +/datum/surgery_status/proc/start_surgery(obj/item/organ/target_organ, target_zone) + LAZYADD(ongoing_steps, target_zone) + LAZYADDASSOC(operated_organs, target_zone, target_organ) + +/datum/surgery_status/proc/stop_surgery(target_zone) + LAZYREMOVE(ongoing_steps, target_zone) + LAZYREMOVE(operated_organs, target_zone) diff --git a/code/datums/surgery/surgery_step.dm b/code/datums/surgery/surgery_step.dm new file mode 100644 index 00000000000..36cadb65f19 --- /dev/null +++ b/code/datums/surgery/surgery_step.dm @@ -0,0 +1,138 @@ +/datum/surgery_step + var/can_infect = FALSE + var/accessible = FALSE + var/delicate = FALSE + var/blood_level = 0 + var/shock_level = 0 + var/priority = 0 + var/duration = 0 + var/list/allowed_tools = null + +/// tool check -> organ selection -> organ checks -> surgery init -> orher stuff +/datum/surgery_step/proc/do_step(atom/user, mob/living/carbon/human/target, obj/item/tool, target_zone) + if(!check_tool(tool)) + return FALSE + + if(accessible && !check_clothing(target, target_zone)) + return FALSE + + var/obj/item/organ/target_organ = target.get_organ(pick_organ_tag(user, target, target_zone)) + if(!check_organ(target, target_organ, tool, target_zone)) + return FALSE + + // At this point we can access selected organ via `surgery_status`. + target.surgery_status.start_surgery(target_organ, target_zone) + initiate(user, target, tool, target_zone) + target.surgery_status.stop_surgery(target_zone) + + target.update_surgery() + + return TRUE + +/datum/surgery_step/proc/check_tool(obj/item/tool) + var/bool = (tool.type in allowed_tools) + return bool + +/datum/surgery_step/proc/check_clothing(mob/living/carbon/target, target_zone) + var/list/clothes = get_target_clothes(target, target_zone) + for(var/obj/item/clothing/C in clothes) + if(C.body_parts_covered & body_part_flags[target_zone]) + return FALSE + return TRUE + +/datum/surgery_step/proc/check_organ(mob/living/carbon/human/target, obj/item/organ/target_organ, obj/item/tool, target_zone) + if(!istype(target_organ)) + return FALSE + + return TRUE + +/datum/surgery_step/proc/pick_organ_tag(atom/user, mob/living/carbon/target, target_zone) + return target_zone + +/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone) + var/obj/item/target_organ = target.surgery_status.operated_organs[target_zone] + if(can_infect && target_organ) + spread_germs_to_organ(user, target_organ) + + if(ishuman(user) && prob(60)) + var/mob/living/carbon/human/H = user + if(blood_level & BLOODY_HANDS) + H.bloody_hands(target, 0) + if(blood_level & BLOODY_BODY) + H.bloody_body(target, 0) + + if(shock_level) + target.shock_stage = max(target.shock_stage, shock_level) + + var/success_chance = calc_success_chance(user, target, tool) + var/surgery_duration = SURGERY_DURATION_DELTA * duration * tool.surgery_speed + if(prob(success_chance) && do_mob(user, target, surgery_duration)) + success(user, target, tool, target_zone) + else + failure(user, target, tool, target_zone) + +/datum/surgery_step/proc/spread_germs_to_organ(mob/living/carbon/human/user, obj/item/organ/external/target_organ) + if(!istype(user) || !istype(target_organ)) + return + + var/germ_level = user.germ_level + var/obj/item/clothing/gloves/G = user.gloves + if(istype(G) && !(G.clipped && prob(75))) + germ_level = G.germ_level + + target_organ.germ_level = max(germ_level, target_organ.germ_level) + +/datum/surgery_step/proc/calc_success_chance(mob/living/user, mob/living/carbon/human/target, obj/item/tool, target_zone) + . = allowed_tools[tool.type] + if(user == target) + . -= 10 + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + . -= round(H.shock_stage * 0.5) + if(H.eye_blurry) + . -= 20 + if(H.eye_blind) + . -= 60 + + if(delicate) + if(ishuman(user) && user?.slurring) + . -= 10 + if(!target.lying) + . -= 30 + + var/turf/T = get_turf(target) + if(locate(/obj/machinery/optable, T)) + . -= 0 + else if(locate(/obj/structure/bed, T)) + . -= 5 + else if(locate(/obj/structure/table, T)) + . -= 10 + else if(locate(/obj/effect/rune/, T)) + . -= 10 + + . = max(., 0) + +/datum/surgery_step/proc/success(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone) + pass() + +/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone) + pass() + +/datum/surgery_step/proc/announce_preop(mob/living/user, self_message, blind_message) + user.visible_message( + self_message, + blind_message + ) + +/datum/surgery_step/proc/announce_success(mob/living/user, self_message, blind_message) + user.visible_message( + SPAN("notice", self_message), + SPAN("notice", blind_message) + ) + +/datum/surgery_step/proc/announce_failure(mob/living/user, self_message, blind_message) + user.visible_message( + SPAN("warning", self_message), + SPAN("warning", blind_message) + ) From e5e53e4aa86f1daaf2845d2d832cd3a8b031391c Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 11 Oct 2023 11:40:08 +0300 Subject: [PATCH 03/37] update surgery_status field init --- code/modules/mob/living/carbon/carbon.dm | 2 +- code/modules/mob/living/carbon/carbon_defines.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 6f5814975a2..210eae02e54 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -14,7 +14,7 @@ /mob/living/carbon/Destroy() QDEL_NULL(touching) QDEL_NULL(bloodstr) - QDEL_NULL(op_stage) + QDEL_NULL(surgery_status) reagents = null //We assume reagents is a reference to bloodstr here diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 67072f8e9fd..fa02fc1241a 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -8,7 +8,7 @@ var/life_tick = 0 // The amount of life ticks that have processed on this mob. var/obj/item/handcuffed = null //Whether or not the mob is handcuffed //Surgery info - var/datum/surgery_status/op_stage = new /datum/surgery_status + var/datum/surgery_status/surgery_status = new() var/analgesic = 0 // when this is set, the mob isn't affected by shock or pain //Active emote/pose var/pose = null From 61ffe896c5b7a7f03dab033f1a6cc8a41e01f9a5 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 11 Oct 2023 11:40:44 +0300 Subject: [PATCH 04/37] temporary disable medical integrated circuits --- .../subtypes/medical.dm | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/code/modules/integrated_electronics/subtypes/medical.dm b/code/modules/integrated_electronics/subtypes/medical.dm index 193a7e0abab..75afb8b84f1 100644 --- a/code/modules/integrated_electronics/subtypes/medical.dm +++ b/code/modules/integrated_electronics/subtypes/medical.dm @@ -66,7 +66,7 @@ QDEL_NULL(st) if(istype(I, /obj/item/organfixer/advanced)) operation_intent = SURGERY_ORGAN_HEAL - st = new /datum/surgery_step/internal/fix_organ_multiple() +// st = new /datum/surgery_step/internal/fix_organ_multiple() /obj/item/integrated_circuit/medical/surgery_device/get_selected_zone() return selected_zone @@ -134,9 +134,9 @@ if(!selected_zone || !(selected_zone in BP_ALL_LIMBS)) activate_pin(3) return - if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. - activate_pin(3) - return + // if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. + // activate_pin(3) + // return var/status = do_int_surgery(H) if(status && !(status == SURGERY_FAILURE || status == SURGERY_BLOCKED)) @@ -150,7 +150,7 @@ return TRUE /obj/item/integrated_circuit/medical/surgery_device/proc/do_int_surgery(mob/living/carbon/M) - for(var/datum/surgery_step/S in surgery_steps) + for(var/datum/surgery_step/S in GLOB.surgery_steps) if(istype(S, /datum/surgery_step/internal) && S.type != st?.type) continue var/status = do_real_surgery(M, S) @@ -160,15 +160,15 @@ /obj/item/integrated_circuit/medical/surgery_device/proc/do_real_surgery(mob/living/carbon/M, datum/surgery_step/S, use_integrated_circuit_can_use_check = FALSE, obj/item/organ/organ) //check if tool is right or close enough and if this step is possible - var/obj/item/user = get_object() - if(S.tool_quality(instrument)) - var/step_is_valid - if(use_integrated_circuit_can_use_check) - step_is_valid = can_use(M, organ, selected_zone) - else - step_is_valid = S.can_use(user, M, selected_zone, instrument) - if(step_is_valid && S.is_valid_target(M)) - return S.do_surgery_process(M, user, selected_zone, instrument, step_is_valid) + //var/obj/item/user = get_object() + // if(S.tool_quality(instrument)) + // var/step_is_valid + // if(use_integrated_circuit_can_use_check) + // step_is_valid = can_use(M, organ, selected_zone) + // else + // step_is_valid = S.can_use(user, M, selected_zone, instrument) + // if(step_is_valid && S.is_valid_target(M)) + // return S.do_surgery_process(M, user, selected_zone, instrument, step_is_valid) return SURGERY_FAILED_STATE // for checks... /* SUBTYPES. @@ -202,22 +202,22 @@ return if(istype(I, /obj/item/scalpel)) operation_intent = SURGERY_ORGAN_DISCONNECT - st = new /datum/surgery_step/internal/detatch_organ() +// st = new /datum/surgery_step/internal/detatch_organ() else if(istype(I, /obj/item/hemostat)) operation_intent = SURGERY_ORGAN_REMOVE - st = new /datum/surgery_step/internal/remove_organ() +// st = new /datum/surgery_step/internal/remove_organ() else if(istype(I, /obj/item/FixOVein)) operation_intent = SURGERY_ORGAN_CONNECT - st = new /datum/surgery_step/internal/attach_organ() +// st = new /datum/surgery_step/internal/attach_organ() else if(istype(I, /obj/item/organfixer)) operation_intent = SURGERY_ORGAN_HEAL - st = new /datum/surgery_step/internal/fix_organ() +// st = new /datum/surgery_step/internal/fix_organ() else if(istype(I, /obj/item/reagent_containers/dropper)) operation_intent = SURGERY_ORGAN_TREAT - st = new /datum/surgery_step/internal/treat_necrosis() +// st = new /datum/surgery_step/internal/treat_necrosis() else operation_intent = SURGERY_ORGAN_INSERT - st = new /datum/surgery_step/internal/replace_organ() +// st = new /datum/surgery_step/internal/replace_organ() /obj/item/integrated_circuit/medical/surgery_device/internal/do_work(ord) var/mob/living/carbon/human/H = get_pin_data(IC_INPUT, 1) @@ -234,9 +234,9 @@ if(!selected_zone || !(selected_zone in BP_ALL_LIMBS)) activate_pin(3) return - if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. - activate_pin(3) - return + // if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. + // activate_pin(3) + // return if(operation_intent == SURGERY_ORGAN_INSERT) E = H.organs_by_name[O.parent_organ] else @@ -261,12 +261,12 @@ return FALSE /obj/item/integrated_circuit/medical/surgery_device/internal/can_use(mob/living/carbon/human/target, obj/item/organ/internal/organ, target_zone) - if(operation_intent == SURGERY_ORGAN_INSERT) - return st.can_use(src, target, target_zone, organ) - else - st.ignore_tool = TRUE - st.preselected_organ = organ - return st.can_use(src, target, target_zone, instrument) + // if(operation_intent == SURGERY_ORGAN_INSERT) + // return st.can_use(src, target, target_zone, organ) + // else + // st.ignore_tool = TRUE + // st.preselected_organ = organ + // return st.can_use(src, target, target_zone, instrument) /obj/item/integrated_circuit/medical/surgery_device/face name = "plastic surgery device" From a0e6c949c03c8fca7611d877b90fb1b38adf28e2 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Sat, 14 Oct 2023 13:20:10 +0300 Subject: [PATCH 05/37] properly disable medical circuits --- baystation12.dme | 1 - .../subtypes/medical.dm | 62 +++++++++---------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index 305b9635bdd..1e4a895abd8 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1861,7 +1861,6 @@ #include "code\modules\integrated_electronics\subtypes\lists.dm" #include "code\modules\integrated_electronics\subtypes\logic.dm" #include "code\modules\integrated_electronics\subtypes\manipulation.dm" -#include "code\modules\integrated_electronics\subtypes\medical.dm" #include "code\modules\integrated_electronics\subtypes\memory.dm" #include "code\modules\integrated_electronics\subtypes\mining.dm" #include "code\modules\integrated_electronics\subtypes\output.dm" diff --git a/code/modules/integrated_electronics/subtypes/medical.dm b/code/modules/integrated_electronics/subtypes/medical.dm index 75afb8b84f1..8b1931cce31 100644 --- a/code/modules/integrated_electronics/subtypes/medical.dm +++ b/code/modules/integrated_electronics/subtypes/medical.dm @@ -1,5 +1,3 @@ -#define SURGERY_FAILURE -1 -#define SURGERY_BLOCKED -2 #define SURGERY_ORGAN_REMOVE 0 #define SURGERY_ORGAN_INSERT 1 #define SURGERY_ORGAN_HEAL 2 @@ -66,7 +64,7 @@ QDEL_NULL(st) if(istype(I, /obj/item/organfixer/advanced)) operation_intent = SURGERY_ORGAN_HEAL -// st = new /datum/surgery_step/internal/fix_organ_multiple() + st = new /datum/surgery_step/internal/fix_organ_multiple() /obj/item/integrated_circuit/medical/surgery_device/get_selected_zone() return selected_zone @@ -134,9 +132,9 @@ if(!selected_zone || !(selected_zone in BP_ALL_LIMBS)) activate_pin(3) return - // if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. - // activate_pin(3) - // return + if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. + activate_pin(3) + return var/status = do_int_surgery(H) if(status && !(status == SURGERY_FAILURE || status == SURGERY_BLOCKED)) @@ -159,16 +157,16 @@ return FALSE /obj/item/integrated_circuit/medical/surgery_device/proc/do_real_surgery(mob/living/carbon/M, datum/surgery_step/S, use_integrated_circuit_can_use_check = FALSE, obj/item/organ/organ) - //check if tool is right or close enough and if this step is possible - //var/obj/item/user = get_object() - // if(S.tool_quality(instrument)) - // var/step_is_valid - // if(use_integrated_circuit_can_use_check) - // step_is_valid = can_use(M, organ, selected_zone) - // else - // step_is_valid = S.can_use(user, M, selected_zone, instrument) - // if(step_is_valid && S.is_valid_target(M)) - // return S.do_surgery_process(M, user, selected_zone, instrument, step_is_valid) + check if tool is right or close enough and if this step is possible + var/obj/item/user = get_object() + if(S.tool_quality(instrument)) + var/step_is_valid + if(use_integrated_circuit_can_use_check) + step_is_valid = can_use(M, organ, selected_zone) + else + step_is_valid = S.can_use(user, M, selected_zone, instrument) + if(step_is_valid && S.is_valid_target(M)) + return S.do_surgery_process(M, user, selected_zone, instrument, step_is_valid) return SURGERY_FAILED_STATE // for checks... /* SUBTYPES. @@ -202,22 +200,22 @@ return if(istype(I, /obj/item/scalpel)) operation_intent = SURGERY_ORGAN_DISCONNECT -// st = new /datum/surgery_step/internal/detatch_organ() + st = new /datum/surgery_step/internal/detatch_organ() else if(istype(I, /obj/item/hemostat)) operation_intent = SURGERY_ORGAN_REMOVE -// st = new /datum/surgery_step/internal/remove_organ() + st = new /datum/surgery_step/internal/remove_organ() else if(istype(I, /obj/item/FixOVein)) operation_intent = SURGERY_ORGAN_CONNECT -// st = new /datum/surgery_step/internal/attach_organ() + st = new /datum/surgery_step/internal/attach_organ() else if(istype(I, /obj/item/organfixer)) operation_intent = SURGERY_ORGAN_HEAL -// st = new /datum/surgery_step/internal/fix_organ() + st = new /datum/surgery_step/internal/fix_organ() else if(istype(I, /obj/item/reagent_containers/dropper)) operation_intent = SURGERY_ORGAN_TREAT -// st = new /datum/surgery_step/internal/treat_necrosis() + st = new /datum/surgery_step/internal/treat_necrosis() else operation_intent = SURGERY_ORGAN_INSERT -// st = new /datum/surgery_step/internal/replace_organ() + st = new /datum/surgery_step/internal/replace_organ() /obj/item/integrated_circuit/medical/surgery_device/internal/do_work(ord) var/mob/living/carbon/human/H = get_pin_data(IC_INPUT, 1) @@ -234,9 +232,9 @@ if(!selected_zone || !(selected_zone in BP_ALL_LIMBS)) activate_pin(3) return - // if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. - // activate_pin(3) - // return + if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. + activate_pin(3) + return if(operation_intent == SURGERY_ORGAN_INSERT) E = H.organs_by_name[O.parent_organ] else @@ -261,12 +259,12 @@ return FALSE /obj/item/integrated_circuit/medical/surgery_device/internal/can_use(mob/living/carbon/human/target, obj/item/organ/internal/organ, target_zone) - // if(operation_intent == SURGERY_ORGAN_INSERT) - // return st.can_use(src, target, target_zone, organ) - // else - // st.ignore_tool = TRUE - // st.preselected_organ = organ - // return st.can_use(src, target, target_zone, instrument) + if(operation_intent == SURGERY_ORGAN_INSERT) + return st.can_use(src, target, target_zone, organ) + else + st.ignore_tool = TRUE + st.preselected_organ = organ + return st.can_use(src, target, target_zone, instrument) /obj/item/integrated_circuit/medical/surgery_device/face name = "plastic surgery device" @@ -602,8 +600,6 @@ push_data() activate_pin(2) -#undef SURGERY_FAILURE -#undef SURGERY_BLOCKED #undef SURGERY_ORGAN_REMOVE #undef SURGERY_ORGAN_INSERT #undef SURGERY_ORGAN_HEAL From 3343211df777b63b1e7be6820cafb11450bb16c1 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Sat, 14 Oct 2023 13:39:52 +0300 Subject: [PATCH 06/37] improve surgery step code & add documentation --- code/datums/surgery/_defines.dm | 4 +- code/datums/surgery/surgery_status.dm | 2 + code/datums/surgery/surgery_step.dm | 185 ++++++++++++++++++++++---- 3 files changed, 165 insertions(+), 26 deletions(-) diff --git a/code/datums/surgery/_defines.dm b/code/datums/surgery/_defines.dm index b40bfe993dd..682f8880abe 100644 --- a/code/datums/surgery/_defines.dm +++ b/code/datums/surgery/_defines.dm @@ -6,8 +6,8 @@ /// Delta multiplier for all surgeries, ranges from 0.9 to 1.1. #define SURGERY_DURATION_DELTA rand(9, 11) / 10 -#define SURGERY_FAILURE -1 -#define SURGERY_BLOCKED -2 +#define SURGERY_FAILURE -1 +#define SURGERY_BLOCKED -2 #define CUT_DURATION 30 #define AMPUTATION_DURATION 125 diff --git a/code/datums/surgery/surgery_status.dm b/code/datums/surgery/surgery_status.dm index e8d72abb8ad..95b648fd28c 100644 --- a/code/datums/surgery/surgery_status.dm +++ b/code/datums/surgery/surgery_status.dm @@ -6,6 +6,8 @@ /** * Associative list of string -> type, where string is zone name and * type is a reference to an operated organ. + * + * Exists 'cause of integrated crcuits. */ var/list/operated_organs = list() diff --git a/code/datums/surgery/surgery_step.dm b/code/datums/surgery/surgery_step.dm index 36cadb65f19..6681d65b67c 100644 --- a/code/datums/surgery/surgery_step.dm +++ b/code/datums/surgery/surgery_step.dm @@ -1,57 +1,167 @@ /datum/surgery_step + /// Whether performing this step can cause infection. var/can_infect = FALSE + /// Whether this step require not covered organ. var/accessible = FALSE + /// Whether this step can be successfully performed on any surface. var/delicate = FALSE + /** + * Bitflag, whther this step would make user covered in blood. + * * 0 - nothing. + * * BLOODY_BODY - makes body covered in blood. + * * BLOODY_HANDS - makes hands covered in blood. + */ var/blood_level = 0 + /// Level of shock to be apllied on target when performing this step. var/shock_level = 0 + /// Priority, steps with higher priority would be called first during step macthing. var/priority = 0 + /// Duration of step in deciseconds. var/duration = 0 + /// Associative list of typepath -> value, where typepath is surgery tool and value is chance to succeed from 0 to 100. var/list/allowed_tools = null -/// tool check -> organ selection -> organ checks -> surgery init -> orher stuff +/** + * Performs preop checks and fires step if succeeded. + * + * Vars: + * * user - atom that fired this step. + * * target - human mob over which this step would be fired. + * * tool - tool used on target. + * * target_zone - zone selected by user when using tool on target mob. + * + * Checks tool. + * + * Checks whether zone is used by another step. + * + * Checks clothing. + * + * Checks parent and target organ. + * + * Adds operated organ to target's operated_organs associative list. + * + * Initiates step. + * + * Removes operated organ from operated_organs. + * + * Updates target's icon. + * + */ /datum/surgery_step/proc/do_step(atom/user, mob/living/carbon/human/target, obj/item/tool, target_zone) - if(!check_tool(tool)) + if(!get_tool_quality(tool)) + return FALSE + + var/parent_zone = get_parent_zone(target_zone) + if(!check_zone(target, parent_zone)) return FALSE if(accessible && !check_clothing(target, target_zone)) return FALSE - var/obj/item/organ/target_organ = target.get_organ(pick_organ_tag(user, target, target_zone)) - if(!check_organ(target, target_organ, tool, target_zone)) + var/obj/item/organ/parent_organ = target.get_organ(parent_zone) + var/obj/item/organ/target_organ = target.get_organ(target_zone || override_tag(user, target, target_zone)) + if(!check_organs(parent_organ, target_organ, target, tool)) return FALSE // At this point we can access selected organ via `surgery_status`. - target.surgery_status.start_surgery(target_organ, target_zone) - initiate(user, target, tool, target_zone) - target.surgery_status.stop_surgery(target_zone) + target.surgery_status.start_surgery(target_organ, parent_zone) + initiate(parent_organ, target_organ, target, tool, user) + target.surgery_status.stop_surgery(parent_zone) target.update_surgery() return TRUE -/datum/surgery_step/proc/check_tool(obj/item/tool) - var/bool = (tool.type in allowed_tools) - return bool +/** + * Checks if type of tool is present in allowed_tools and returns value + * associated with it, FALSE otherwise. + */ +/datum/surgery_step/proc/get_tool_quality(obj/item/tool) + for(var/typepath as anything in allowed_tools) + if(!istype(tool, typepath)) + continue + return allowed_tools[typepath] + + return FALSE + +/// Checks if zone is valid and is not used by other steps. +/datum/surgery_step/proc/check_zone(mob/living/carbon/human/target, target_zone) + if(target_zone in target.surgery_status.ongoing_steps) + return FALSE + + return TRUE -/datum/surgery_step/proc/check_clothing(mob/living/carbon/target, target_zone) +/// Checks if zone is covered by clothing. +/datum/surgery_step/proc/check_clothing(mob/living/carbon/human/target, target_zone) var/list/clothes = get_target_clothes(target, target_zone) for(var/obj/item/clothing/C in clothes) if(C.body_parts_covered & body_part_flags[target_zone]) return FALSE + return TRUE -/datum/surgery_step/proc/check_organ(mob/living/carbon/human/target, obj/item/organ/target_organ, obj/item/tool, target_zone) - if(!istype(target_organ)) +/// Returns parent organ's tag depending on zone, currently used by eyes only. +/datum/surgery_step/proc/get_parent_zone(target_zone) + if(target_zone == BP_EYES || target_zone == BP_MOUTH) + return BP_HEAD + + return target_zone + +/** + * Override to change target tag to organ tag of your choice. If zone is present + * in target's operated_organs returns its tag, null otherwise. + * + * Vars: + * * user - atom that fired this step. + * * target - human mob this step is fired upon. + * * target_zone - zone selected by user. + */ +/datum/surgery_step/proc/override_tag(atom/user, mob/living/carbon/target, target_zone) + var/parent_zone = get_parent_zone(target_zone) + var/obj/item/organ/preselected_organ = target.surgery_status.operated_organs[parent_zone] + if(istype(preselected_organ)) + return preselected_organ.organ_tag + + return null + +/** + * Performs checks on parent and target organ, override to add extra ones. + * + * Vars: + * * parent_organ - external organ, where target organ is located. + * * target_organ - target organ, can be equal to parent. + * * target - human mob this step is fired upon. + * * tool - tool used to fire this step. + * + * Checks if parent and target organs are present. + */ +/datum/surgery_step/proc/check_organs(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool) + if(!istype(parent_organ) || !istype(target_organ)) return FALSE return TRUE -/datum/surgery_step/proc/pick_organ_tag(atom/user, mob/living/carbon/target, target_zone) - return target_zone - -/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone) - var/obj/item/target_organ = target.surgery_status.operated_organs[target_zone] - if(can_infect && target_organ) +/** + * Initiates surgery step, override to add extra messages and injuries. + * + * Vars: + * * parent_organ - external organ, where target organ is located. + * * target_organ - target organ, can be equal to parent. + * * target - human mob this step is fired upon. + * * tool - tool used to fire this step. + * * user - atom that fired this step. + * + * Infects organ if `can_infect` set to TRUE. + * + * Applies blood on users body and hands if corresponding flags are present. + * + * Applies shock effect if value is present. + * + * Calls `success` or `failure` proc based on success chance. + * + */ +/datum/surgery_step/proc/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + if(can_infect) spread_germs_to_organ(user, target_organ) if(ishuman(user) && prob(60)) @@ -67,10 +177,11 @@ var/success_chance = calc_success_chance(user, target, tool) var/surgery_duration = SURGERY_DURATION_DELTA * duration * tool.surgery_speed if(prob(success_chance) && do_mob(user, target, surgery_duration)) - success(user, target, tool, target_zone) + success(parent_organ, target_organ, target, tool, user) else - failure(user, target, tool, target_zone) + failure(parent_organ, target_organ, target, tool, user) +/// Spreads germs to organ if no gloves is present. /datum/surgery_step/proc/spread_germs_to_organ(mob/living/carbon/human/user, obj/item/organ/external/target_organ) if(!istype(user) || !istype(target_organ)) return @@ -82,8 +193,9 @@ target_organ.germ_level = max(germ_level, target_organ.germ_level) +/// Calculates success chance based on users health conditions, surface and target. /datum/surgery_step/proc/calc_success_chance(mob/living/user, mob/living/carbon/human/target, obj/item/tool, target_zone) - . = allowed_tools[tool.type] + . = get_tool_quality(tool) if(user == target) . -= 10 @@ -113,24 +225,49 @@ . = max(., 0) -/datum/surgery_step/proc/success(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone) +/** + * Called on step success, override to apply effects on target and print out + * extra fluff. + * + * Vars: + * * parent_organ - external organ, where target organ is located. + * * target_organ - target organ, can be equal to parent. + * * target - human mob this step is fired upon. + * * tool - tool used to fire this step. + * * user - atom that fired this step. + */ +/datum/surgery_step/proc/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) pass() -/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/human/target, obj/item/tool, target_zone) +/** + * Called on step failure, override to apply effects on target and print out + * extra fluff. + * + * Vars: + * * parent_organ - external organ, where target organ is located. + * * target_organ - target organ, can be equal to parent. + * * target - human mob this step is fired upon. + * * tool - tool used to fire this step. + * * user - atom that fired this step. + */ +/datum/surgery_step/proc/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) pass() +/// Prints out visible message. /datum/surgery_step/proc/announce_preop(mob/living/user, self_message, blind_message) user.visible_message( self_message, blind_message ) +/// Prints out visible message with "notice" class. /datum/surgery_step/proc/announce_success(mob/living/user, self_message, blind_message) user.visible_message( SPAN("notice", self_message), SPAN("notice", blind_message) ) +/// Prints out visible message with "warning" class. /datum/surgery_step/proc/announce_failure(mob/living/user, self_message, blind_message) user.visible_message( SPAN("warning", self_message), From 81f6a28fdd6d49afd9e9a0ac8fcbf5ca1a7c4dc9 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Sun, 15 Oct 2023 14:54:30 +0300 Subject: [PATCH 07/37] add more proc checks to surgery step --- code/datums/surgery/surgery_step.dm | 50 ++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/code/datums/surgery/surgery_step.dm b/code/datums/surgery/surgery_step.dm index 6681d65b67c..34c9e684ead 100644 --- a/code/datums/surgery/surgery_step.dm +++ b/code/datums/surgery/surgery_step.dm @@ -36,7 +36,7 @@ * * Checks clothing. * - * Checks parent and target organ. + * Checks parent and posiibly overriden target organ. * * Adds operated organ to target's operated_organs associative list. * @@ -48,6 +48,9 @@ * */ /datum/surgery_step/proc/do_step(atom/user, mob/living/carbon/human/target, obj/item/tool, target_zone) + if(!hasorgans(target)) + return FALSE + if(!get_tool_quality(tool)) return FALSE @@ -59,14 +62,17 @@ return FALSE var/obj/item/organ/parent_organ = target.get_organ(parent_zone) - var/obj/item/organ/target_organ = target.get_organ(target_zone || override_tag(user, target, target_zone)) - if(!check_organs(parent_organ, target_organ, target, tool)) + if(!check_parent_organ(parent_organ, target, tool)) + return FALSE + + var/obj/item/organ/target_organ = pick_target_organ(user, target, target_zone) + if(!check_target_organ(target_organ, target, tool)) return FALSE // At this point we can access selected organ via `surgery_status`. target.surgery_status.start_surgery(target_organ, parent_zone) initiate(parent_organ, target_organ, target, tool, user) - target.surgery_status.stop_surgery(parent_zone) + target.surgery_status.stop_surgery(target_organ, parent_zone) target.update_surgery() @@ -108,35 +114,47 @@ return target_zone /** - * Override to change target tag to organ tag of your choice. If zone is present - * in target's operated_organs returns its tag, null otherwise. + * Returns organ from 'organs_by_name' associative list based on tag, override + * to rerturn something else. * * Vars: * * user - atom that fired this step. * * target - human mob this step is fired upon. * * target_zone - zone selected by user. */ -/datum/surgery_step/proc/override_tag(atom/user, mob/living/carbon/target, target_zone) - var/parent_zone = get_parent_zone(target_zone) - var/obj/item/organ/preselected_organ = target.surgery_status.operated_organs[parent_zone] - if(istype(preselected_organ)) - return preselected_organ.organ_tag - - return null +/datum/surgery_step/proc/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + return target.get_organ(target_zone) /** - * Performs checks on parent and target organ, override to add extra ones. + * Performs checks on parent a.e external organ, override to add extra ones. * * Vars: * * parent_organ - external organ, where target organ is located. + * * target - human mob this step is fired upon. + * * tool - tool used to fire this step. + * * user - atom that fired this step. + * + * Checks if parent and target organs are present. + */ +/datum/surgery_step/proc/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + if(!istype(parent_organ)) + return FALSE + + return TRUE + +/** + * Performs checks on target organ, override to add extra ones. + * + * Vars: * * target_organ - target organ, can be equal to parent. * * target - human mob this step is fired upon. * * tool - tool used to fire this step. + * * user - atom that fired this step. * * Checks if parent and target organs are present. */ -/datum/surgery_step/proc/check_organs(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool) - if(!istype(parent_organ) || !istype(target_organ)) +/datum/surgery_step/proc/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + if(!istype(target_organ)) return FALSE return TRUE From b7fde6890a92a470eea12027a41703efb2fb3d4f Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:19:52 +0300 Subject: [PATCH 08/37] convert bone surgery steps --- code/datums/surgery/steps/bone.dm | 270 ++++++++++++++++++++++++++++++ code/modules/surgery/bones.dm | 215 ------------------------ 2 files changed, 270 insertions(+), 215 deletions(-) create mode 100644 code/datums/surgery/steps/bone.dm delete mode 100644 code/modules/surgery/bones.dm diff --git a/code/datums/surgery/steps/bone.dm b/code/datums/surgery/steps/bone.dm new file mode 100644 index 00000000000..aa562c6b353 --- /dev/null +++ b/code/datums/surgery/steps/bone.dm @@ -0,0 +1,270 @@ +/** + * Default bone surgery step, does nothing. + */ +/datum/surgery_step/bone + can_infect = TRUE + blood_level = BLOODY_HANDS + shock_level = 20 + +/datum/surgery_step/bone/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return . + + if(BP_IS_ROBOTIC(parent_organ)) + return FALSE + + return parent_organ.open() >= SURGERY_RETRACTED + +/** + * Bone glueing step. + */ +/datum/surgery_step/bone/glue_bone + duration = GLUE_BONE_DURATION + allowed_tools = list( + /obj/item/bonegel = 100, + /obj/item/tape_roll = 75 + ) + +/datum/surgery_step/bone/glue_bone/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.stage == 0) + +/datum/surgery_step/bone/glue_bone/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/bone = parent_organ.encased ? "[target]'s [parent_organ.encased]" : "bones in [target]'s [parent_organ]" + announce_preop(user, + "[user] starts applying \the [tool] to the [bone].", + "You start applying \the [tool] to the [bone]." + ) + target.custom_pain( + "Something in your [parent_organ] is causing you a lot of pain!", + 50, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/bone/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/bone = parent_organ.encased ? "[target]'s [parent_organ.encased]" : "bones in [target]'s [parent_organ]" + announce_success(user, + "[user] applies some [tool.name] to [bone]", + "You apply some [tool.name] to [bone]." + ) + parent_organ.stage = 1 + +/datum/surgery_step/glue_bone/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, smearing [tool] in the incision in [target]'s [parent_organ]!", + "Your hand slips, smearing [tool] in the incision in [target]'s [parent_organ]!" + ) + +/** + * Bone mending step, used on all bodypart except head. + */ +/datum/surgery_step/bone/mend_bone + duration = BONE_MEND_DURATION + shock_level = 40 + delicate = TRUE + + allowed_tools = list( + /obj/item/bonesetter = 100, + /obj/item/wrench = 75 + ) + +/datum/surgery_step/bone/mend_bone/check_zone(mob/living/carbon/human/target, target_zone) + return (..() && target_zone == BP_HEAD) + +/datum/surgery_step/bone/mend_bone/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.stage == 1) + +/datum/surgery_step/bone/mend_bone/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] is beginning to piece together [target]'s skull with \the [tool].", + "You are beginning to piece together [target]'s skull with \the [tool]." + ) + return ..() + +/datum/surgery_step/bone/mend_bone/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] sets [target]'s skull with \the [tool].", + "You set [target]'s skull with \the [tool]." + ) + parent_organ.stage = 2 + +/datum/surgery_step/bone/mend_bone/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, damaging [target]'s face with \the [tool]!", + "Your hand slips, damaging [target]'s face with \the [tool]!" + ) + parent_organ.take_external_damage(10, used_weapon = tool) + parent_organ.status |= ORGAN_DISFIGURED + +/** + * Skull mending step. + */ +/datum/surgery_step/bone/mend_skull + delicate = TRUE + shock_level = 40 + duration = BONE_MEND_DURATION + + allowed_tools = list( + /obj/item/bonesetter = 100, + /obj/item/wrench = 75 + ) + +/datum/surgery_step/bone/mend_skull/check_zone(mob/living/carbon/human/target, target_zone) + return (..() && target_zone == BP_HEAD) + +/datum/surgery_step/bone/mend_skull/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.stage == 1) + +/datum/surgery_step/bone/mend_skull/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] is beginning to piece together [target]'s skull with \the [tool].", + "You are beginning to piece together [target]'s skull with \the [tool]." + ) + return ..() + +/datum/surgery_step/bone/mend_skull/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] sets [target]'s skull with \the [tool].", + "You set [target]'s skull with \the [tool]." + ) + parent_organ.stage = 2 + +/datum/surgery_step/bone/mend_skull/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, damaging [target]'s face with \the [tool]!", + "Your hand slips, damaging [target]'s face with \the [tool]!" + ) + parent_organ.take_external_damage(10, used_weapon = tool) + parent_organ.status |= ORGAN_DISFIGURED + +/** + * Bone setting step. + */ +/datum/surgery_step/bone/set_bone + shock_level = 40 + delicate = TRUE + duration = BONE_MEND_DURATION + allowed_tools = list( + /obj/item/bonesetter = 100, + /obj/item/wrench = 75 + ) + +/datum/surgery_step/bone/set_bone/check_zone(mob/living/carbon/human/target, target_zone) + return (..() && target_zone != BP_HEAD) + +/datum/surgery_step/bone/set_bone/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.stage == 1) + +/datum/surgery_step/bone/set_bone/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/bone = parent_organ.encased ? "[target]'s [parent_organ.encased]" : "bones in [target]'s [parent_organ]" + announce_preop(user, + "[user] is beginning to set the [bone] in place with \the [tool].", + "You are beginning to set the [bone] in place with \the [tool]." + ) + target.custom_pain( + "The pain in your [parent_organ] is going to make you pass out!", + 50, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/bone/set_bone/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/bone = parent_organ.encased ? "[target]'s [parent_organ.encased]" : "bones in [target]'s [parent_organ]" + if(parent_organ.status & ORGAN_BROKEN) + announce_success(user, + "[user] sets the [bone] in place with \the [tool].", + "You set the [bone] in place with \the [tool]." + ) + parent_organ.stage = 2 + else + announce_success(user, + "[user] sets the [bone]" + SPAN("warning", " in the WRONG place with \the [tool]."), + "You set the [bone]" + SPAN("warning", " in the WRONG place with \the [tool].") + ) + parent_organ.fracture() + +/datum/surgery_step/bone/set_bone/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, damaging the [parent_organ.encased ? parent_organ.encased : "bones"] in [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, damaging the [parent_organ.encased ? parent_organ.encased : "bones"] in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.fracture() + parent_organ.take_external_damage(5, used_weapon = tool) + +/** + * Applies bonegel on set bone. + */ +/datum/surgery_step/bone/postset_bone + duration = GLUE_BONE_DURATION + + allowed_tools = list( + /obj/item/bonegel = 100, + /obj/item/tape_roll = 75 + ) + +/datum/surgery_step/bone/postset_bone/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.stage == 2) + +/datum/surgery_step/bone/postset_bone/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/bone = parent_organ.encased ? "[target]'s [parent_organ.encased]" : "bones in [target]'s [parent_organ]" + announce_preop(user, + "[user] starts to finish mending the damaged [bone] with \the [tool].", + "You start to finish mending the damaged [bone] with \the [tool]." + ) + return ..() + +/datum/surgery_step/bone/postset_bone/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/bone = parent_organ.encased ? "[target]'s [parent_organ.encased]" : "bones in [target]'s [parent_organ]" + announce_success(user, + "[user] has mended the damaged [bone] with \the [tool].", + "You have mended the damaged [bone] with \the [tool]." + ) + parent_organ.mend_fracture() + parent_organ.stage = 0 + +/datum/surgery_step/bone/postset_bone/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, smearing [tool] in the incision in [target]'s [parent_organ]!", + "Your hand slips, smearing [tool] in the incision in [target]'s [parent_organ]!" + ) + +/** + * All-in-one operation using bone mender. + */ +/datum/surgery_step/bone/mender + duration = BONE_MEND_DURATION + + allowed_tools = list( + /obj/item/bonesetter/bone_mender = 100 + ) + +/datum/surgery_step/bone/mender/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.stage <= 5) + +/datum/surgery_step/bone/mender/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts grasping the damaged bone edges in [target]'s [parent_organ] with \the [tool].", + "You start grasping the bone edges and fusing them in [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain( + "Something in your [parent_organ] is causing you a lot of pain!", + 50, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/bone/mender/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has grasped the damaged bone edges in [target]'s [parent_organ] with \the [tool].", + "You have grasped the damaged bone edges in [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.mend_fracture() + parent_organ.stage = 0 + +/datum/surgery_step/bone/mender/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "\The [tool] in [user]'s hand skips, jabbing the bone edges into the sides of [target]'s [parent_organ]!", + "Your hand jolts and \the [tool] skips, jabbing the bone edges into [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage(10, used_weapon = tool) diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm deleted file mode 100644 index 8045bfd2a1e..00000000000 --- a/code/modules/surgery/bones.dm +++ /dev/null @@ -1,215 +0,0 @@ -//Procedures in this file: Fracture repair surgery -////////////////////////////////////////////////////////////////// -// BONE SURGERY // -////////////////////////////////////////////////////////////////// - - - - - -////////////////////////////////////////////////////////////////// -// bone gelling surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/glue_bone - allowed_tools = list( - /obj/item/bonegel = 100, - /obj/item/tape_roll = 75 - ) - can_infect = 1 - blood_level = 1 - - duration = GLUE_BONE_DURATION - shock_level = 20 - -/datum/surgery_step/glue_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !BP_IS_ROBOTIC(affected) && affected.open() >= 2 && affected.stage == 0 - -/datum/surgery_step/glue_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/bone = affected.encased ? "[target]'s [affected.encased]" : "bones in [target]'s [affected.name]" - if (affected.stage == 0) - user.visible_message("[user] starts applying \the [tool] to the [bone]." , \ - "You start applying \the [tool] to the [bone].") - target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",50, affecting = affected) - ..() - -/datum/surgery_step/glue_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/bone = affected.encased ? "[target]'s [affected.encased]" : "bones in [target]'s [affected.name]" - user.visible_message(SPAN_NOTICE("[user] applies some [tool.name] to [bone]"), \ - SPAN_NOTICE("You apply some [tool.name] to [bone].")) - affected.stage = 1 - -/datum/surgery_step/glue_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(SPAN_WARNING("[user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") , \ - SPAN_WARNING("Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!")) - - -////////////////////////////////////////////////////////////////// -// bone setting surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/set_bone - allowed_tools = list( - /obj/item/bonesetter = 100, \ - /obj/item/wrench = 75 \ - ) - - duration = BONE_MEND_DURATION - shock_level = 40 - delicate = 1 - -/datum/surgery_step/set_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.organ_tag != BP_HEAD && !BP_IS_ROBOTIC(affected) && affected.open() >= SURGERY_RETRACTED && affected.stage == 1 - -/datum/surgery_step/set_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/bone = affected.encased ? "[target]'s [affected.encased]" : "bones in [target]'s [affected.name]" - user.visible_message("[user] is beginning to set the [bone] in place with \the [tool]." , \ - "You are beginning to set the [bone] in place with \the [tool].") - target.custom_pain("The pain in your [affected.name] is going to make you pass out!", 50, affecting = affected) - ..() - -/datum/surgery_step/set_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/bone = affected.encased ? "[target]'s [affected.encased]" : "bones in [target]'s [affected.name]" - if (affected.status & ORGAN_BROKEN) - user.visible_message(SPAN_NOTICE("[user] sets the [bone] in place with \the [tool]."), \ - SPAN_NOTICE("You set the [bone] in place with \the [tool].")) - affected.stage = 2 - else - user.visible_message(SPAN_NOTICE("[user] sets the [bone]") + SPAN_WARNING(" in the WRONG place with \the [tool]."), \ - SPAN_NOTICE("You set the [bone]") + SPAN_WARNING(" in the WRONG place with \the [tool].")) - affected.fracture() - -/datum/surgery_step/set_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(SPAN_WARNING("[user]'s hand slips, damaging the [affected.encased ? affected.encased : "bones"] in [target]'s [affected.name] with \the [tool]!") , \ - SPAN_WARNING("Your hand slips, damaging the [affected.encased ? affected.encased : "bones"] in [target]'s [affected.name] with \the [tool]!")) - affected.fracture() - affected.take_external_damage(5, used_weapon = tool) - - -////////////////////////////////////////////////////////////////// -// skull mending surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/mend_skull - allowed_tools = list( - /obj/item/bonesetter = 100, \ - /obj/item/wrench = 75 \ - ) - - duration = BONE_MEND_DURATION - shock_level = 40 - delicate = 1 - -/datum/surgery_step/mend_skull/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.organ_tag == BP_HEAD && !BP_IS_ROBOTIC(affected) && affected.open() >= SURGERY_RETRACTED && affected.stage == 1 - -/datum/surgery_step/mend_skull/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] is beginning to piece together [target]'s skull with \the [tool]." , \ - "You are beginning to piece together [target]'s skull with \the [tool].") - ..() - -/datum/surgery_step/mend_skull/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(SPAN_NOTICE("[user] sets [target]'s skull with \the [tool].") , \ - SPAN_NOTICE("You set [target]'s skull with \the [tool].")) - affected.stage = 2 - -/datum/surgery_step/mend_skull/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(SPAN_WARNING("[user]'s hand slips, damaging [target]'s face with \the [tool]!") , \ - SPAN_WARNING("Your hand slips, damaging [target]'s face with \the [tool]!")) - var/obj/item/organ/external/head/h = affected - affected.take_external_damage(10, used_weapon = tool) - h.status |= ORGAN_DISFIGURED - -////////////////////////////////////////////////////////////////// -// post setting bone-gelling surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/finish_bone - allowed_tools = list( - /obj/item/bonegel = 100, \ - /obj/item/tape_roll = 75 - ) - can_infect = 1 - blood_level = 1 - - duration = GLUE_BONE_DURATION - shock_level = 20 - -/datum/surgery_step/finish_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open() >= SURGERY_RETRACTED && !BP_IS_ROBOTIC(affected) && affected.stage == 2 - -/datum/surgery_step/finish_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/bone = affected.encased ? "[target]'s [affected.encased]" : "bones in [target]'s [affected.name]" - user.visible_message("[user] starts to finish mending the damaged [bone] with \the [tool].", \ - "You start to finish mending the damaged [bone] with \the [tool].") - ..() - -/datum/surgery_step/finish_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - var/bone = affected.encased ? "[target]'s [affected.encased]" : "bones in [target]'s [affected.name]" - - user.visible_message(SPAN("notice", "[user] has mended the damaged [bone] with \the [tool]."), \ - SPAN("notice", "You have mended the damaged [bone] with \the [tool].") ) - affected.mend_fracture() - affected.stage = 0 - -/datum/surgery_step/finish_bone/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(SPAN_WARNING("[user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") , \ - SPAN_WARNING("Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!")) - -//////BONE MENDER///////// -/datum/surgery_step/bone_mender - allowed_tools = list( - /obj/item/bonesetter/bone_mender = 100, - ) - - can_infect = 1 - blood_level = 1 - - duration = BONE_MEND_DURATION - shock_level = 20 - -/datum/surgery_step/bone_mender/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !BP_IS_ROBOTIC(affected) && affected.open() >= 2 && affected.stage == 0 - -/datum/surgery_step/bone_mender/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected.stage <= 5) - user.visible_message("[user] starts grasping the damaged bone edges in [target]'s [affected.name] with \the [tool]." , \ - "You start grasping the bone edges and fusing them in [target]'s [affected.name] with \the [tool].") - target.custom_pain("Something in your [affected.name] is causing you a lot of pain!", 50, affecting = affected) - ..() - -/datum/surgery_step/bone_mender/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] has grasped the damaged bone edges in [target]'s [affected.name] with \the [tool].") , \ - SPAN_NOTICE("You have grasped the damaged bone edges in [target]'s [affected.name] with \the [tool].") ) - affected.mend_fracture() - affected.stage = 0 - -/datum/surgery_step/bone_mender/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("\The [tool] in [user]'s hand skips, jabbing the bone edges into the sides of [target]'s [affected.name]!") , \ - SPAN_WARNING("Your hand jolts and \the [tool] skips, jabbing the bone edges into [target]'s [affected.name] with \the [tool]!")) - affected.take_external_damage(10, used_weapon = tool) From 864b5b0ef5758f43021f5e0ff1c5b7e8448b5e5b Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:20:29 +0300 Subject: [PATCH 09/37] convert limb surgery steps --- code/datums/surgery/_defines.dm | 2 + code/datums/surgery/steps/limb.dm | 193 ++++++++++++++++++++++++++ code/modules/surgery/limb_reattach.dm | 163 ---------------------- 3 files changed, 195 insertions(+), 163 deletions(-) create mode 100644 code/datums/surgery/steps/limb.dm delete mode 100644 code/modules/surgery/limb_reattach.dm diff --git a/code/datums/surgery/_defines.dm b/code/datums/surgery/_defines.dm index 682f8880abe..5ba9b81857a 100644 --- a/code/datums/surgery/_defines.dm +++ b/code/datums/surgery/_defines.dm @@ -21,3 +21,5 @@ #define ATTACH_DURATION 50 #define ORGAN_FIX_DURATION 35 #define CONNECT_DURATION 50 +#define STERILIZATION_DURATION 55 +#define DETATCH_DURATION 52 diff --git a/code/datums/surgery/steps/limb.dm b/code/datums/surgery/steps/limb.dm new file mode 100644 index 00000000000..4df87aec38d --- /dev/null +++ b/code/datums/surgery/steps/limb.dm @@ -0,0 +1,193 @@ +/** + * Default limb attachment step, does nothing. + */ +/datum/surgery_step/limb + accessible = FALSE + delicate = TRUE + shock_level = 40 + priority = 3 // Must be higher than /datum/surgery_step/internal. + +/datum/surgery_step/limb/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return TRUE + +/datum/surgery_step/limb/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return TRUE + +/** + * Attaches external limb. + */ +/datum/surgery_step/limb/attach_organic + duration = ATTACH_DURATION + + allowed_tools = list( + /obj/item/organ/external = 100 + ) + +/datum/surgery_step/limb/attach_organic/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + var/obj/item/organ/external/E = tool + if(!istype(E)) + return FALSE + + var/obj/item/organ/external/L = target.get_organ(E.organ_tag) + if(!isnull(L)) + return FALSE + + var/obj/item/organ/external/P = target.get_organ(E.parent_organ) + if(isnull(P) || P.is_stump()) + return FALSE + + if(BP_IS_ROBOTIC(P) && !BP_IS_ROBOTIC(E)) + return FALSE + + return !isnull(target.species.has_limbs["[E.organ_tag]"]) + +/datum/surgery_step/limb/attach_organic/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/organ/external/E = tool + user.visible_message( + "[user] starts attaching [E] to [target]'s [E.amputation_point].", + "You start attaching [E] to [target]'s [E.amputation_point]." + ) + return ..() + +/datum/surgery_step/limb/attach_organic/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + if(!user.drop(tool)) + return + + var/obj/item/organ/external/E = tool + announce_success(user, + "[user] has attached [target]'s [E] to the [E.amputation_point].", + "You have attached [target]'s [E] to the [E.amputation_point]." + ) + E.replaced(target) + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + +/datum/surgery_step/limb/attach_organic/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/organ/external/E = tool + var/obj/item/organ/external/P = target.organs_by_name[E.parent_organ] + announce_failure(user, + "[user]'s hand slips, damaging [target]'s [E.amputation_point]!", + "Your hand slips, damaging [target]'s [E.amputation_point]!" + ) + target.apply_damage( + 10, + BRUTE, + P, + damage_flags = DAM_SHARP + ) + +/** + * Connects attached limbs to targets body. + */ +/datum/surgery_step/limb/connect + can_infect = TRUE + duration = CLAMP_DURATION + + allowed_tools = list( + /obj/item/hemostat = 100, + /obj/item/stack/cable_coil = 75, + /obj/item/device/assembly/mousetrap = 20 + ) + +/datum/surgery_step/limb/connect/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return . + + if(parent_organ.is_stump()) + return FALSE + + return (parent_organ.status & ORGAN_CUT_AWAY) + +/datum/surgery_step/limb/connect/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] starts connecting tendons and muscles in [target]'s [parent_organ.amputation_point] with [tool].", + "You start connecting tendons and muscle in [target]'s [parent_organ.amputation_point]." + ) + return ..() + +/datum/surgery_step/limb/connect/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user] has connected tendons and muscles in [target]'s [parent_organ.amputation_point] with [tool].", + "You have connected tendons and muscles in [target]'s [parent_organ.amputation_point] with [tool]." + ) + parent_organ.status &= ~ORGAN_CUT_AWAY + if(parent_organ.children) + for(var/obj/item/organ/external/C in parent_organ.children) + C.status &= ~ORGAN_CUT_AWAY + C.update_tally() + parent_organ.update_tally() + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + +/datum/surgery_step/limb/connect/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure( + "[user]'s hand slips, damaging [target]'s [parent_organ.amputation_point]!", + "Your hand slips, damaging [target]'s [parent_organ.amputation_point]!" + ) + target.apply_damage( + 10, + BRUTE, + target.organs_by_name[parent_organ.parent_organ], + damage_flags = DAM_SHARP + ) + +/** + * Attaches robot part as a limb. + */ +/datum/surgery_step/limb/mechanize + duration = ATTACH_DURATION + + allowed_tools = list( + /obj/item/robot_parts = 100 + ) + +/datum/surgery_step/limb/mechanize/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + var/obj/item/robot_parts/P = tool + return isnull(target.get_organ(P.bp_tag)) + +/datum/surgery_step/limb/mechanize/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts attaching \the [tool] to [target].", + "You start attaching \the [tool] to [target]." + ) + return ..() + +/datum/surgery_step/limb/mechanize/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/robot_parts/L = tool + if(!L.part) + return + + for(var/oragn_tag in L.part) + if(!isnull(target.get_organ(oragn_tag))) + continue + + var/list/organ_data = target.species.has_limbs["[oragn_tag]"] + if(!organ_data) + continue + + var/limb_path = organ_data["path"] + var/obj/item/organ/external/new_limb = new limb_path(target) + new_limb.robotize(L.model_info) + if(L.sabotaged) + new_limb.status |= ORGAN_SABOTAGED + + announce_success(user, + "[user] has attached \the [tool] to [target].", + "You have attached \the [tool] to [target]." + ) + + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + + qdel(tool) + +/datum/surgery_step/limb/mechanize/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, damaging [target]'s flesh!", + "Your hand slips, damaging [target]'s flesh!" + ) + target.apply_damage(10, BRUTE, null, damage_flags = DAM_SHARP) diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm deleted file mode 100644 index 514b8c54672..00000000000 --- a/code/modules/surgery/limb_reattach.dm +++ /dev/null @@ -1,163 +0,0 @@ -//Procedures in this file: Robotic limbs attachment, meat limbs attachment -////////////////////////////////////////////////////////////////// -// LIMB SURGERY // -////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////// -// generic limb surgery step datum -////////////////////////////////////////////////////////////////// -/datum/surgery_step/limb/ - priority = 3 // Must be higher than /datum/surgery_step/internal - can_infect = 0 - shock_level = 40 - delicate = 1 - clothes_penalty = FALSE - -/datum/surgery_step/limb/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - - var/obj/item/organ/external/E = tool - - if(!istype(E)) - return 0 - - var/obj/item/organ/external/P = target.organs_by_name[E.parent_organ] - if(!P || P.is_stump()) - to_chat(user, SPAN("notice", "The [E.amputation_point] is missing!")) - return SURGERY_FAILURE - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(affected) - return SURGERY_FAILURE - if(E.organ_tag != check_zone(target_zone)) // Somehow this is safe to use. All hail the glorious bayspaghetti! - to_chat(user, SPAN("notice", "You manage to realize that \the [E] does not belong here.")) - return SURGERY_FAILURE - var/list/organ_data = target.species.has_limbs["[target_zone]"] - return !isnull(organ_data) - -////////////////////////////////////////////////////////////////// -// limb attachment surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/limb/attach - allowed_tools = list(/obj/item/organ/external = 100) - - duration = ATTACH_DURATION - -/datum/surgery_step/limb/attach/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - user.visible_message("[user] starts attaching [E.name] to [target]'s [E.amputation_point].", \ - "You start attaching [E.name] to [target]'s [E.amputation_point].") - -/datum/surgery_step/limb/attach/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!user.drop(tool)) - return - var/obj/item/organ/external/E = tool - user.visible_message("[user] has attached [target]'s [E.name] to the [E.amputation_point].", \ - "You have attached [target]'s [E.name] to the [E.amputation_point].") - E.replaced(target) - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() - -/datum/surgery_step/limb/attach/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = tool - var/obj/item/organ/external/P = target.organs_by_name[E.parent_organ] - user.visible_message(" [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ - " Your hand slips, damaging [target]'s [E.amputation_point]!") - target.apply_damage(10, BRUTE, P, damage_flags=DAM_SHARP) - -////////////////////////////////////////////////////////////////// -// limb connecting surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/limb/connect - allowed_tools = list( - /obj/item/hemostat = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/device/assembly/mousetrap = 20 - ) - can_infect = 1 - - duration = CLAMP_DURATION - -/datum/surgery_step/limb/connect/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - return E && !E.is_stump() && (E.status & ORGAN_CUT_AWAY) - -/datum/surgery_step/limb/connect/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - user.visible_message("[user] starts connecting tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "You start connecting tendons and muscle in [target]'s [E.amputation_point].") - -/datum/surgery_step/limb/connect/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - user.visible_message("[user] has connected tendons and muscles in [target]'s [E.amputation_point] with [tool].", \ - "You have connected tendons and muscles in [target]'s [E.amputation_point] with [tool].") - E.status &= ~ORGAN_CUT_AWAY - if(E.children) - for(var/obj/item/organ/external/C in E.children) - C.status &= ~ORGAN_CUT_AWAY - C.update_tally() - E.update_tally() - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() - -/datum/surgery_step/limb/connect/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/E = target.get_organ(target_zone) - var/obj/item/organ/external/P = target.organs_by_name[E.parent_organ] - user.visible_message(" [user]'s hand slips, damaging [target]'s [E.amputation_point]!", \ - " Your hand slips, damaging [target]'s [E.amputation_point]!") - target.apply_damage(10, BRUTE, P, damage_flags=DAM_SHARP) - -////////////////////////////////////////////////////////////////// -// robotic limb attachment surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/limb/mechanize - allowed_tools = list(/obj/item/robot_parts = 100) - - duration = ATTACH_DURATION - -/datum/surgery_step/limb/mechanize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/robot_parts/p = tool - if (p.part) - if (!(target_zone in p.part)) - return 0 - return isnull(target.get_organ(target_zone)) - -/datum/surgery_step/limb/mechanize/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts attaching \the [tool] to [target].", \ - "You start attaching \the [tool] to [target].") - -/datum/surgery_step/limb/mechanize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/robot_parts/L = tool - user.visible_message("[user] has attached \the [tool] to [target].", \ - "You have attached \the [tool] to [target].") - - if(L.part) - for(var/part_name in L.part) - if(!isnull(target.get_organ(part_name))) - continue - var/list/organ_data = target.species.has_limbs["[part_name]"] - if(!organ_data) - continue - var/new_limb_type = organ_data["path"] - var/obj/item/organ/external/new_limb = new new_limb_type(target) - new_limb.robotize(L.model_info) - if(L.sabotaged) - new_limb.status |= ORGAN_SABOTAGED - - target.update_body() - target.updatehealth() - target.UpdateDamageIcon() - - qdel(tool) - -/datum/surgery_step/limb/mechanize/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) - var/obj/item/organ/external/P = target.organs_by_name[affected.parent_organ] - user.visible_message(" [user]'s hand slips, damaging [target]'s flesh!", \ - " Your hand slips, damaging [target]'s flesh!") - target.apply_damage(10, BRUTE, P, damage_flags=DAM_SHARP) From d40dc769fa92b461ee7b487b41a1ae65a18a6eb8 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:21:11 +0300 Subject: [PATCH 10/37] convert generic surgery steps --- code/datums/surgery/steps/generic.dm | 445 +++++++++++++++++++++++++++ code/modules/surgery/generic.dm | 336 -------------------- 2 files changed, 445 insertions(+), 336 deletions(-) create mode 100644 code/datums/surgery/steps/generic.dm delete mode 100644 code/modules/surgery/generic.dm diff --git a/code/datums/surgery/steps/generic.dm b/code/datums/surgery/steps/generic.dm new file mode 100644 index 00000000000..3cf7bf8d407 --- /dev/null +++ b/code/datums/surgery/steps/generic.dm @@ -0,0 +1,445 @@ +/** + * Default generic step, does nothing. + */ +/datum/surgery_step/generic + can_infect = TRUE + shock_level = 10 + /// Whether parent organ is required not to be a stump. + var/check_stump = TRUE + +/datum/surgery_step/generic/check_zone(target_zone) + return ..() && target_zone != BP_EYES + +/datum/surgery_step/generic/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return . + + if(check_stump && parent_organ.is_stump()) + return FALSE + + return !BP_IS_ROBOTIC(parent_organ) + +/datum/surgery_step/generic/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return TRUE + +/** + * Cauterizes incision. + */ +/datum/surgery_step/generic/cauterize + allowed_tools = list( + /obj/item/cautery = 100, + /obj/item/clothing/mask/smokable/cigarette = 75, + /obj/item/flame/lighter = 50, + /obj/item/weldingtool = 25, + /obj/item/hothands = 20 + ) + + duration = CAUTERIZE_DURATION + check_stump = FALSE + +/datum/surgery_step/generic/cauterize/check_zone(target_zone) + return (..() && target_zone != BP_MOUTH) + +/datum/surgery_step/generic/cauterize/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return . + + if(!parent_organ.get_incision(TRUE)) + return FALSE + + if(parent_organ.is_stump()) + return parent_organ.status & ORGAN_ARTERY_CUT + + return parent_organ.open() + +/datum/surgery_step/generic/cauterize/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/datum/wound/cut/W = parent_organ.get_incision() + announce_preop(user, + "[user] is beginning to cauterize[W ? " \a [W.desc] on" : ""] \the [target]'s [parent_organ] with \the [tool].", + "You are beginning to cauterize[W ? " \a [W.desc] on" : ""] \the [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain( + "Your [parent_organ] is being burned!", + 40, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/generic/cauterize/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/datum/wound/cut/W = parent_organ.get_incision() + announce_success(user, + "[user] cauterizes[W ? " \a [W.desc] on" : ""] \the [target]'s [parent_organ] with \the [tool].", + "You cauterize[W ? " \a [W.desc] on" : ""] \the [target]'s [parent_organ] with \the [tool]." + ) + if(parent_organ.clamped()) + parent_organ.remove_clamps() + if(parent_organ.is_stump()) + parent_organ.status &= ~ORGAN_ARTERY_CUT + W?.close() + +/datum/surgery_step/generic/cauterize/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, leaving a small burn on [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, leaving a small burn on [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage(0, 3, used_weapon = tool) + + +/** + * Default icision with scalpel, nothing extra. + */ +/datum/surgery_step/generic/cut_open + duration = CUT_DURATION + + allowed_tools = list( + /obj/item/scalpel = 100, + /obj/item/material/knife = 75, + /obj/item/material/kitchen/utensil/knife = 75, + /obj/item/broken_bottle = 50, + /obj/item/material/shard = 50 + ) + +/datum/surgery_step/generic/cut_open/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && !parent_organ.open()) + +/datum/surgery_step/generic/cut_open/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts the incision on [target]'s [parent_organ] with \the [tool].", + "You start the incision on [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain( + "You feel a horrible pain as if from a sharp knife in your [parent_organ]!", + 40, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/generic/cut_open/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has made an incision on [target]'s [parent_organ] with \the [tool].", + "You have made an incision on [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.createwound(CUT, parent_organ.min_broken_damage / 2, 1) + playsound(target.loc, 'sound/weapons/bladeslice.ogg', 15, 1) + +/datum/surgery_step/generic/cut_open/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, slicing open [target]'s [parent_organ] in the wrong place with \the [tool]!", + "Your hand slips, slicing open [target]'s [parent_organ] in the wrong place with \the [tool]!" + ) + parent_organ.take_external_damage( + 10, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + +/** + * Incision made with laser scalpel, clamps bleeders. + */ +/datum/surgery_step/generic/cut_with_laser + priority = 2 + duration = CUT_DURATION + + allowed_tools = list( + /obj/item/scalpel/laser3 = 100, + /obj/item/scalpel/laser2 = 100, + /obj/item/scalpel/laser1 = 100, + /obj/item/melee/energy/sword/one_hand = 50 + ) + +/datum/surgery_step/generic/cut_with_laser/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && !parent_organ.open()) + +/datum/surgery_step/generic/cut_with_laser/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts the bloodless incision on [target]'s [parent_organ] with \the [tool].", + "You start the bloodless incision on [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain( + "You feel a horrible, searing pain in your [parent_organ]!", + 50, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/generic/cut_with_laser/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has made a bloodless incision on [target]'s [parent_organ] with \the [tool].", + "You have made a bloodless incision on [target]'s [parent_organ] with \the [tool].", + ) + parent_organ.createwound(CUT, parent_organ.min_broken_damage / 2, 1) + parent_organ.clamp_organ() + spread_germs_to_organ(user, parent_organ) + +/datum/surgery_step/generic/cut_with_laser/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips as the blade sputters, searing a long gash in [target]'s [parent_organ] with \the [tool]!", + "Your hand slips as the blade sputters, searing a long gash in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage( + 15, + 5, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + +/** + * Incision made using incision manager, clamps bleeders and retracts skin. + */ +/datum/surgery_step/generic/incision_manager + priority = 2 + duration = CUT_DURATION + + allowed_tools = list( + /obj/item/scalpel/manager = 100 + ) + +/datum/surgery_step/generic/incision_manager/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) + return (..() && (parent_organ.open() == SURGERY_CLOSED || parent_organ.open() == SURGERY_OPEN)) + +/datum/surgery_step/generic/incision_manager/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + if(parent_organ.open() == SURGERY_CLOSED) + announce_preop(user, + "[user] starts to construct a prepared incision on [target]'s [parent_organ] with \the [tool].", + "You carefully start incision on [target]'s [parent_organ], while \the [tool] makes all the side work for you." + ) + else + announce_preop(user, + "[user] starts sliding \the [tool] above the cut on [target]'s [parent_organ].", + "You carefully start sliding \the [tool] above the cut on [target]'s [parent_organ], while it makes all the side work for you." + ) + target.custom_pain( + "You feel a horrible, searing pain in your [parent_organ] as it is pushed apart!", + 50, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/generic/incision_manager/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has constructed a prepared incision on [target]'s [parent_organ] with \the [tool].", + "You have constructed a prepared incision on [target]'s [parent_organ] with \the [tool]." + ) + if(parent_organ.open() == SURGERY_CLOSED) + parent_organ.createwound(CUT, parent_organ.min_broken_damage / 2, 1) + parent_organ.clamp_organ() + parent_organ.open_incision() + +/datum/surgery_step/generic/incision_manager/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand jolts as the system sparks, ripping a gruesome hole in [target]'s [parent_organ] with \the [tool]!", + "Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage( + 20, + 15, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + +/** + * Clamps bleeders. + */ +/datum/surgery_step/generic/clamp_bleeders + duration = CLAMP_DURATION + + allowed_tools = list( + /obj/item/hemostat = 100, + /obj/item/stack/cable_coil = 75, + /obj/item/device/assembly/mousetrap = 20 + ) + +/datum/surgery_step/generic/clamp_bleeders/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.open() && !parent_organ.clamped()) + +/datum/surgery_step/generic/clamp_bleeders/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts clamping bleeders in [target]'s [parent_organ] with \the [tool].", + "You start clamping bleeders in [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain( + "The pain in your [parent_organ] is maddening!", + 40, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/generic/clamp_bleeders/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] clamps bleeders in [target]'s [parent_organ] with \the [tool].", + "You clamp bleeders in [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.clamp_organ() + spread_germs_to_organ(user, parent_organ) + +/datum/surgery_step/generic/clamp_bleeders/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage( + 10, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + +/** + * Retracts skin around incision. + */ +/datum/surgery_step/generic/retract_skin + allowed_tools = list( + /obj/item/retractor = 100, + /obj/item/crowbar = 75, + /obj/item/material/knife = 50, + /obj/item/material/kitchen/utensil/fork = 50 + ) + + priority = 1 + duration = RETRACT_DURATION + +/datum/surgery_step/generic/retract_skin/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.open() == SURGERY_OPEN) + +/datum/surgery_step/generic/retract_skin/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts to pry open the incision on [target]'s [parent_organ] with \the [tool].", + "You start to pry open the incision on [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain( + "It feels like the skin on your [parent_organ] is on fire!", + 40, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/generic/retract_skin/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] keeps the incision open on [target]'s [parent_organ] with \the [tool].", + "You keep the incision open on [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.open_incision() + +/datum/surgery_step/generic/retract_skin/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, tearing the edges of the incision on [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, tearing the edges of the incision on [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage( + 12, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + +/** + * Saws off bones, covering interal organs. + */ +/datum/surgery_step/generic/saw + can_infect = TRUE + delicate = TRUE + blood_level = BLOODY_HANDS + shock_level = 40 + priority = 2 + duration = SAW_DURATION + + allowed_tools = list( + /obj/item/circular_saw = 100, + /obj/item/material/knife = 50, + /obj/item/material/hatchet = 75 + ) + +/datum/surgery_step/generic/saw/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.open() == SURGERY_RETRACTED) + +/datum/surgery_step/generic/saw/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] begins to cut through [target]'s [parent_organ.encased] with \the [tool].", + "You begin to cut through [target]'s [parent_organ.encased] with \the [tool]." + ) + target.custom_pain( + "Something hurts horribly in your [parent_organ]!", + 60, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/generic/saw/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has cut [target]'s [parent_organ.encased] open with \the [tool].", + "You have cut [target]'s [parent_organ.encased] open with \the [tool]." + ) + parent_organ.fracture() + +/datum/surgery_step/generic/saw/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, cracking [target]'s [parent_organ.encased] with \the [tool]!" , + "Your hand slips, cracking [target]'s [parent_organ.encased] with \the [tool]!" + ) + parent_organ.take_external_damage( + 15, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + parent_organ.fracture() + +/** + * Amputates limb. + */ +/datum/surgery_step/generic/amputate + duration = AMPUTATION_DURATION + check_stump = FALSE + + allowed_tools = list( + /obj/item/circular_saw = 100, + /obj/item/material/hatchet = 75, + /obj/item/material/twohanded/fireaxe = 85, + /obj/item/gun/energy/plasmacutter = 90 + ) + +/datum/surgery_step/generic/amputate/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && !parent_organ.open() && (parent_organ.limb_flags & ORGAN_FLAG_CAN_AMPUTATE)) + +/datum/surgery_step/generic/amputate/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] is beginning to amputate [target]'s [parent_organ] with \the [tool].", + "You are beginning to cut through [target]'s [parent_organ.amputation_point] with \the [tool]." + ) + target.custom_pain( + "Your [parent_organ.amputation_point] is being ripped apart!", + 100, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/generic/amputate/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] amputates [target]'s [parent_organ] at the [parent_organ.amputation_point] with \the [tool].", + "You amputate [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.droplimb(TRUE, DROPLIMB_EDGE) + +/datum/surgery_step/generic/amputate/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, sawing through the bone in [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, sawwing through the bone in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage(30, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) + parent_organ.fracture() + +/datum/surgery_step/generic/amputate/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, sawing through the bone in [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, sawwing through the bone in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage( + 30, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + parent_organ.fracture() diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm deleted file mode 100644 index 4a9fa783844..00000000000 --- a/code/modules/surgery/generic.dm +++ /dev/null @@ -1,336 +0,0 @@ -//Procedures in this file: Generic surgery steps -////////////////////////////////////////////////////////////////// -// COMMON STEPS // -////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////// -// generic surgery step datum -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/ - can_infect = 1 - shock_level = 10 - -/datum/surgery_step/generic/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (ismetroid(target)) - return 0 - if (target_zone == BP_EYES) //there are specific steps for eye surgery - return 0 - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected == null) - return 0 - if (affected.is_stump()) - return 0 - return !BP_IS_ROBOTIC(affected) - -////////////////////////////////////////////////////////////////// -// laser scalpel surgery step -// acts as both cutting and bleeder clamping surgery steps -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/cut_with_laser - allowed_tools = list( - /obj/item/scalpel/laser3 = 100, \ - /obj/item/scalpel/laser2 = 100, \ - /obj/item/scalpel/laser1 = 100, \ - /obj/item/melee/energy/sword/one_hand = 50 - ) - priority = 2 - duration = CUT_DURATION - -/datum/surgery_step/generic/cut_with_laser/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open() == SURGERY_CLOSED && target_zone != BP_MOUTH - -/datum/surgery_step/generic/cut_with_laser/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 the bloodless incision on [target]'s [affected.name] with \the [tool].", \ - "You start the bloodless incision on [target]'s [affected.name] with \the [tool].") - target.custom_pain("You feel a horrible, searing pain in your [affected.name]!",50, affecting = affected) - ..() - -/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].",) - affected.createwound(CUT, affected.min_broken_damage/2, 1) - affected.clamp_organ() - 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) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user]'s hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!", \ - "Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!") - affected.take_external_damage(15, 5, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// incision manager surgery step -// acts as the cutting, bleeder clamping, and retractor surgery steps -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/incision_manager - allowed_tools = list( - /obj/item/scalpel/manager = 100 - ) - priority = 2 - duration = CUT_DURATION - -/datum/surgery_step/generic/incision_manager/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && (affected.open() == SURGERY_CLOSED || affected.open() == SURGERY_OPEN) && target_zone != BP_MOUTH - -/datum/surgery_step/generic/incision_manager/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(affected.open() == SURGERY_CLOSED) - user.visible_message("[user] starts to construct a prepared incision on [target]'s [affected.name] with \the [tool].", \ - "You carefully start incision on [target]'s [affected.name], while \the [tool] makes all the side work for you.") - else - user.visible_message("[user] starts sliding \the [tool] above the cut on [target]'s [affected.name].", \ - "You carefully start sliding \the [tool] above the cut on [target]'s [affected.name], while it makes all the side work for you.") - target.custom_pain("You feel a horrible, searing pain in your [affected.name] as it is pushed apart!",50, affecting = affected) - ..() - -/datum/surgery_step/generic/incision_manager/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 constructed a prepared incision on [target]'s [affected.name] with \the [tool].", \ - "You have constructed a prepared incision on [target]'s [affected.name] with \the [tool].",) - - if(affected.open() == SURGERY_CLOSED) - affected.createwound(CUT, affected.min_broken_damage/2, 1) - affected.clamp_organ() - affected.open_incision() - -/datum/surgery_step/generic/incision_manager/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 jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.name] with \the [tool]!", \ - "Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.name] with \the [tool]!") - affected.take_external_damage(20, 15, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// scalpel surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/cut_open - allowed_tools = list( - /obj/item/scalpel = 100, \ - /obj/item/material/knife = 75, \ - /obj/item/material/kitchen/utensil/knife = 75, \ - /obj/item/broken_bottle = 50, - /obj/item/material/shard = 50, \ - ) - - duration = CUT_DURATION - -/datum/surgery_step/generic/cut_open/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!istype(affected)) - return - if(affected.open()) - var/datum/wound/cut/incision = affected.get_incision() - to_chat(user, "The [incision.desc] provides enough access, another incision isn't needed.") - return SURGERY_FAILURE - return target_zone != BP_MOUTH - -/datum/surgery_step/generic/cut_open/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 the incision on [target]'s [affected.name] with \the [tool].", \ - "You start the incision on [target]'s [affected.name] with \the [tool].") - target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.name]!",40, affecting = affected) - ..() - -/datum/surgery_step/generic/cut_open/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 an incision on [target]'s [affected.name] with \the [tool].", \ - "You have made an incision on [target]'s [affected.name] with \the [tool].",) - affected.createwound(CUT, affected.min_broken_damage/2, 1) - playsound(target.loc, 'sound/weapons/bladeslice.ogg', 15, 1) - -/datum/surgery_step/generic/cut_open/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, slicing open [target]'s [affected.name] in the wrong place with \the [tool]!", \ - "Your hand slips, slicing open [target]'s [affected.name] in the wrong place with \the [tool]!") - affected.take_external_damage(10, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// bleeder clamping surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/clamp_bleeders - allowed_tools = list( - /obj/item/hemostat = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/device/assembly/mousetrap = 20 - ) - - duration = CLAMP_DURATION - -/datum/surgery_step/generic/clamp_bleeders/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open() && !affected.clamped() - -/datum/surgery_step/generic/clamp_bleeders/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 clamping bleeders in [target]'s [affected.name] with \the [tool].", \ - "You start clamping bleeders in [target]'s [affected.name] with \the [tool].") - target.custom_pain("The pain in your [affected.name] is maddening!",40, affecting = affected) - ..() - -/datum/surgery_step/generic/clamp_bleeders/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] clamps bleeders in [target]'s [affected.name] with \the [tool].", \ - "You clamp bleeders in [target]'s [affected.name] with \the [tool].") - affected.clamp_organ() - spread_germs_to_organ(affected, user) - playsound(target.loc, 'sound/items/Welder.ogg', 15, 1) - -/datum/surgery_step/generic/clamp_bleeders/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, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ - "Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!",) - affected.take_external_damage(10, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// retractor surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/retract_skin - allowed_tools = list( - /obj/item/retractor = 100, \ - /obj/item/crowbar = 75, - /obj/item/material/knife = 50, \ - /obj/item/material/kitchen/utensil/fork = 50 - ) - - priority = 1 - duration = RETRACT_DURATION - -/datum/surgery_step/generic/retract_skin/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.open() == SURGERY_OPEN //&& !(affected.status & ORGAN_BLEEDING) - -/datum/surgery_step/generic/retract_skin/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 incision on [target]'s [affected.name] with \the [tool].", \ - "You start to pry open the incision on [target]'s [affected.name] with \the [tool].") - target.custom_pain("It feels like the skin on your [affected.name] is on fire!",40,affecting = affected) - ..() - -/datum/surgery_step/generic/retract_skin/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] keeps the incision open on [target]'s [affected.name] with \the [tool].", \ - "You keep the incision open on [target]'s [affected.name] with \the [tool].") - affected.open_incision() - -/datum/surgery_step/generic/retract_skin/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, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!", \ - "Your hand slips, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!") - affected.take_external_damage(12, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// skin cauterization surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/cauterize - allowed_tools = list( - /obj/item/cautery = 100, \ - /obj/item/clothing/mask/smokable/cigarette = 75, \ - /obj/item/flame/lighter = 50, \ - /obj/item/weldingtool = 25, - /obj/item/hothands = 20 - ) - - duration = CAUTERIZE_DURATION - -/datum/surgery_step/generic/cauterize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - - if(target_zone == BP_MOUTH || target_zone == BP_EYES) - return FALSE - if(!hasorgans(target)) - return FALSE - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) - return FALSE - if(BP_IS_ROBOTIC(affected)) - return FALSE - if(!affected.get_incision(1)) - to_chat(user, "There are no incisions on [target]'s [affected.name] that can be closed cleanly with \the [tool]!") - return SURGERY_FAILURE - if(affected.is_stump()) // Copypasting some stuff here to avoid having to modify ..() for a single surgery - return affected.status & ORGAN_ARTERY_CUT - else - return affected.open() - - -/datum/surgery_step/generic/cauterize/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/datum/wound/cut/W = affected.get_incision() - user.visible_message("[user] is beginning to cauterize[W ? " \a [W.desc] on" : ""] \the [target]'s [affected.name] with \the [tool]." , \ - "You are beginning to cauterize[W ? " \a [W.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].") - target.custom_pain("Your [affected.name] is being burned!",40,affecting = affected) - ..() - -/datum/surgery_step/generic/cauterize/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) - var/datum/wound/cut/W = affected.get_incision() - user.visible_message("[user] cauterizes[W ? " \a [W.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].", \ - "You cauterize[W ? " \a [W.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].") - if(affected.clamped()) - affected.remove_clamps() - if(W) - W.close() - if(affected.is_stump()) - affected.status &= ~ORGAN_ARTERY_CUT - -/datum/surgery_step/generic/cauterize/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, leaving a small burn on [target]'s [affected.name] with \the [tool]!", \ - "Your hand slips, leaving a small burn on [target]'s [affected.name] with \the [tool]!") - affected.take_external_damage(0, 3, used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// limb amputation surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/amputate - allowed_tools = list( - /obj/item/circular_saw = 100, \ - /obj/item/material/hatchet = 75, \ - /obj/item/material/twohanded/fireaxe = 85, \ - /obj/item/gun/energy/plasmacutter = 90 - ) - - duration = 125 //hardcoded by design - -/datum/surgery_step/generic/amputate/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (target_zone == BP_EYES) //there are specific steps for eye surgery - return 0 - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected == null) - return 0 - if (affected.open()) - to_chat(user,"You can't get a clean cut with incisions getting in the way.") - return SURGERY_FAILURE - return (affected.limb_flags & ORGAN_FLAG_CAN_AMPUTATE) - -/datum/surgery_step/generic/amputate/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] is beginning to amputate [target]'s [affected.name] with \the [tool]." , \ - "You are beginning to cut through [target]'s [affected.amputation_point] with \the [tool].") - target.custom_pain("Your [affected.amputation_point] is being ripped apart!",100,affecting = affected) - ..() - -/datum/surgery_step/generic/amputate/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] amputates [target]'s [affected.name] at the [affected.amputation_point] with \the [tool].", \ - "You amputate [target]'s [affected.name] with \the [tool].") - affected.droplimb(1,DROPLIMB_EDGE) - -/datum/surgery_step/generic/amputate/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, sawing through the bone in [target]'s [affected.name] with \the [tool]!", \ - "Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!") - affected.take_external_damage(30, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - affected.fracture() From 944f08f8808b1f4899df5d13fff49370906d6c15 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:22:02 +0300 Subject: [PATCH 11/37] update do_surgery proc logic --- code/datums/surgery/surgery_item.dm | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/code/datums/surgery/surgery_item.dm b/code/datums/surgery/surgery_item.dm index a477a625e54..82e234cbec7 100644 --- a/code/datums/surgery/surgery_item.dm +++ b/code/datums/surgery/surgery_item.dm @@ -1,17 +1,12 @@ /obj/item/proc/do_surgery(mob/living/carbon/target, mob/living/user) - if (!istype(target)) + if(!hasorgans(target)) return FALSE - if (user.a_intent == I_HURT) + if(user.a_intent == I_HURT) return FALSE - var/zone = user.zone_sel.selecting - if(zone in target.surgery_status.ongoing_steps) - to_chat(user, SPAN("warning", "You can't operate on this area while surgery is already in progress.")) - return TRUE - for(var/datum/surgery_step/S in GLOB.surgery_steps) - if(S.do_step(user, target, src, zone)) + if(S.do_step(user, target, src, user.zone_sel.selecting)) return TRUE return FALSE From 773ad713b871da7c090bc36f51437dee336ef217 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:23:06 +0300 Subject: [PATCH 12/37] remove old encased steps --- code/modules/surgery/encased.dm | 73 --------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 code/modules/surgery/encased.dm diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm deleted file mode 100644 index 2e8b54bbb36..00000000000 --- a/code/modules/surgery/encased.dm +++ /dev/null @@ -1,73 +0,0 @@ -//Procedures in this file: Generic ribcage opening steps, Removing alien embryo, Fixing internal organs. -////////////////////////////////////////////////////////////////// -// GENERIC RIBCAGE SURGERY // -////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////// -// generic ribcage surgery step datum -////////////////////////////////////////////////////////////////// -/datum/surgery_step/open_encased - priority = 2 - can_infect = 1 - blood_level = 1 - shock_level = 40 - delicate = 1 - -/datum/surgery_step/open_encased/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !BP_IS_ROBOTIC(affected) && affected.encased && affected.open() >= SURGERY_RETRACTED - -////////////////////////////////////////////////////////////////// -// ribcage sawing surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/open_encased/saw - allowed_tools = list( - /obj/item/circular_saw = 100, - /obj/item/material/knife = 50, \ - /obj/item/material/hatchet = 75 - ) - - duration = SAW_DURATION - shock_level = 60 - -/datum/surgery_step/open_encased/saw/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) - return ..() && affected && affected.open() == SURGERY_RETRACTED - -/datum/surgery_step/open_encased/saw/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) - - user.visible_message("[user] begins to cut through [target]'s [affected.encased] with \the [tool].", \ - "You begin to cut through [target]'s [affected.encased] with \the [tool].") - target.custom_pain("Something hurts horribly in your [affected.name]!",60, affecting = affected) - ..() - -/datum/surgery_step/open_encased/saw/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) - - user.visible_message("[user] has cut [target]'s [affected.encased] open with \the [tool].", \ - "You have cut [target]'s [affected.encased] open with \the [tool].") - affected.fracture() - -/datum/surgery_step/open_encased/saw/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, cracking [target]'s [affected.encased] with \the [tool]!" , \ - "Your hand slips, cracking [target]'s [affected.encased] with \the [tool]!" ) - - affected.take_external_damage(15, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - affected.fracture() From e46e088e2498b5b64b997a0f4e7035e255ecd22f Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 18 Oct 2023 20:21:09 +0300 Subject: [PATCH 13/37] prettify old surgery helper procs --- code/_helpers/surgery.dm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/code/_helpers/surgery.dm b/code/_helpers/surgery.dm index 82273874c93..505831159d0 100644 --- a/code/_helpers/surgery.dm +++ b/code/_helpers/surgery.dm @@ -1,20 +1,21 @@ +/// Sorts GLOB surgeries list by priority. /proc/sort_surgeries() var/gap = length(GLOB.surgery_steps) - var/swapped = 1 - while (gap > 1 || swapped) - swapped = 0 + var/swapped = TRUE + while(gap > 1 || swapped) + swapped = FALSE if(gap > 1) gap = round(gap / 1.247330950103979) if(gap < 1) gap = 1 for(var/i = 1; gap + i <= length(GLOB.surgery_steps); i++) - var/datum/surgery_step/l = GLOB.surgery_steps[i] //Fucking hate - var/datum/surgery_step/r = GLOB.surgery_steps[gap+i] //how lists work here + var/datum/surgery_step/l = GLOB.surgery_steps[i] + var/datum/surgery_step/r = GLOB.surgery_steps[gap + i] if(l.priority < r.priority) GLOB.surgery_steps.Swap(i, gap + i) - swapped = 1 + swapped = TRUE -//check if mob is lying down on something we can operate him on. +/// Check if mob is lying down on something we can operate him on. /proc/can_operate(mob/living/carbon/M, mob/living/carbon/user) var/turf/T = get_turf(M) if(locate(/obj/machinery/optable, T)) @@ -38,6 +39,7 @@ if(hitzone in badzones) return FALSE +/// Creates and "centers" organ image for later use inside radial menu. /proc/agjust_organ_image(obj/item/organ/O) var/image/I = image(icon = O.icon, icon_state = O.icon_state) I.overlays = O.overlays From c3d961afbf25aeb7951624c3647448aac841a850 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 18 Oct 2023 20:22:33 +0300 Subject: [PATCH 14/37] add extra checks to prevent tool switching during step --- code/datums/surgery/surgery_step.dm | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/code/datums/surgery/surgery_step.dm b/code/datums/surgery/surgery_step.dm index 34c9e684ead..b3196bb9d60 100644 --- a/code/datums/surgery/surgery_step.dm +++ b/code/datums/surgery/surgery_step.dm @@ -36,7 +36,13 @@ * * Checks clothing. * - * Checks parent and posiibly overriden target organ. + * Checks parent organ. + * + * Picks target organ. + * + * Runs check to ensure that tool was not changed. + * + * Checks target organ. * * Adds operated organ to target's operated_organs associative list. * @@ -66,6 +72,13 @@ return FALSE var/obj/item/organ/target_organ = pick_target_organ(user, target, target_zone) + + var/mob/possible_mob = user + if(istype(possible_mob)) + var/obj/item/active_item = possible_mob.get_active_item() + if(active_item != tool) + return FALSE + if(!check_target_organ(target_organ, target, tool)) return FALSE From f7983555cb0975ac286675374d4a59dcdae8503f Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:30:01 +0300 Subject: [PATCH 15/37] convert internal surgery steps --- code/datums/surgery/_defines.dm | 32 +- code/datums/surgery/steps/internal.dm | 761 +++++++++++++++++++++++ code/modules/surgery/organs_internal.dm | 787 ------------------------ 3 files changed, 776 insertions(+), 804 deletions(-) create mode 100644 code/datums/surgery/steps/internal.dm delete mode 100644 code/modules/surgery/organs_internal.dm diff --git a/code/datums/surgery/_defines.dm b/code/datums/surgery/_defines.dm index 5ba9b81857a..f14419730a6 100644 --- a/code/datums/surgery/_defines.dm +++ b/code/datums/surgery/_defines.dm @@ -6,20 +6,18 @@ /// Delta multiplier for all surgeries, ranges from 0.9 to 1.1. #define SURGERY_DURATION_DELTA rand(9, 11) / 10 -#define SURGERY_FAILURE -1 -#define SURGERY_BLOCKED -2 - -#define CUT_DURATION 30 -#define AMPUTATION_DURATION 125 -#define CLAMP_DURATION 35 -#define RETRACT_DURATION 25 -#define CAUTERIZE_DURATION 35 -#define GLUE_BONE_DURATION 35 -#define BONE_MEND_DURATION 40 -#define SAW_DURATION 50 -#define DRILL_DURATION 70 -#define ATTACH_DURATION 50 -#define ORGAN_FIX_DURATION 35 -#define CONNECT_DURATION 50 -#define STERILIZATION_DURATION 55 -#define DETATCH_DURATION 52 +#define CUT_DURATION 30 +#define AMPUTATION_DURATION 125 +#define CLAMP_DURATION 35 +#define RETRACT_DURATION 25 +#define CAUTERIZE_DURATION 35 +#define GLUE_BONE_DURATION 35 +#define BONE_MEND_DURATION 40 +#define SAW_DURATION 50 +#define DRILL_DURATION 70 +#define ATTACH_DURATION 50 +#define ORGAN_FIX_DURATION 35 +#define CONNECT_DURATION 50 +#define STERILIZATION_DURATION 55 +#define DETATCH_DURATION 52 +#define TREAT_NECROSIS_DURATION 26 diff --git a/code/datums/surgery/steps/internal.dm b/code/datums/surgery/steps/internal.dm new file mode 100644 index 00000000000..4a7da9e0fb4 --- /dev/null +++ b/code/datums/surgery/steps/internal.dm @@ -0,0 +1,761 @@ +/** + * Default internal surgery step, does nothing. + */ +/datum/surgery_step/internal + can_infect = FALSE + blood_level = BLOODY_HANDS + shock_level = 40 + delicate = TRUE + +/datum/surgery_step/internal/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + return target.surgery_status.operated_organs[get_parent_zone(target_zone)] + +/datum/surgery_step/internal/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) + . = ..() + if(!.) + return . + + if(BP_IS_ROBOTIC(parent_organ)) + return parent_organ.hatch_state == HATCH_OPENED + + return parent_organ.open() == (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED) + +/** + * Organ attachment operation via Fix'o Vein, doesn't work on synths. + */ +/datum/surgery_step/internal/attach_organ + duration = CONNECT_DURATION + + allowed_tools = list( + /obj/item/FixOVein = 100, + /obj/item/stack/cable_coil = 75, + /obj/item/tape_roll = 50 + ) + +/datum/surgery_step/internal/attach_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + var/list/attachable_organs = list() + var/obj/item/organ/external/parent_organ = target.get_organ(target_zone) + for(var/obj/item/organ/O in parent_organ.implants) + if(O && (O.status & ORGAN_CUT_AWAY)) + attachable_organs[O] = agjust_organ_image(O) + + var/obj/item/organ/preselected_organ = ..() + if(istype(preselected_organ)) + if(preselected_organ in attachable_organs) + return preselected_organ + + return null + + var/obj/item/organ/selected_organ = show_radial_menu(user, target, attachable_organs, require_near = TRUE) + if(!istype(selected_organ)) + return null + + return selected_organ + +/datum/surgery_step/internal/attach_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) + . = ..() + if(!.) + return + + return !BP_IS_ROBOTIC(parent_organ) + +/datum/surgery_step/internal/attach_organ/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] begins reattaching [target]'s [target_organ] with \the [tool].", + "You start reattaching [target]'s [target_organ] with \the [tool]." + ) + target.custom_pain( + "Someone's digging needles into your [target_organ]!", + 100 + ) + return ..() + +/datum/surgery_step/internal/attach_organ/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has reattached [target]'s [target_organ] with \the [tool].", + "You have reattached [target]'s [target_organ] with \the [tool]." + ) + target_organ.status &= ~ORGAN_CUT_AWAY + parent_organ.implants -= target_organ + target_organ.replaced(target, parent_organ) + target.update_deformities() + +/datum/surgery_step/internal/attach_organ/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, damaging the flesh in [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, damaging the flesh in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage(20, used_weapon = tool) + +/** + * Organ detachment step using any sharp object, doesn't work on sinths. + */ +/datum/surgery_step/internal/detatch_organ + duration = DETATCH_DURATION + + allowed_tools = list( + /obj/item/scalpel = 100, + /obj/item/material/knife = 75, + /obj/item/material/kitchen/utensil/knife = 75, + /obj/item/material/shard = 50 + ) + +/datum/surgery_step/internal/detatch_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) + . = ..() + if(!.) + return . + + return !BP_IS_ROBOTIC(parent_organ) + +/datum/surgery_step/internal/detatch_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + var/list/attached_organs = list() + for(var/obj/item/organ/O in target.internal_organs) + if(O.parent_organ != target_zone) + continue + + if(!(O.status & ORGAN_CUT_AWAY)) + attached_organs[O] = agjust_organ_image(O) + + var/obj/item/organ/preselected_organ = ..() + if(istype(preselected_organ)) + if(preselected_organ in attached_organs) + return preselected_organ + + return null + + var/obj/item/organ/selected_organ = show_radial_menu(user, target, attached_organs, require_near = TRUE) + if(!istype(selected_organ)) + return null + + return selected_organ + +/datum/surgery_step/internal/detatch_organ/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts to separate [target]'s [target_organ] with \the [tool].", + "You start to separate [target]'s [target_organ] with \the [tool]." + ) + target.custom_pain("Someone's ripping out your [target_organ]!", 100) + return ..() + +/datum/surgery_step/internal/detatch_organ/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has separated [target]'s [target_organ] with \the [tool].", + "You have separated [target]'s [target_organ] with \the [tool]." + ) + target_organ.cut_away(target_organ.owner) + +/datum/surgery_step/internal/detatch_organ/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, slicing an artery inside [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, slicing an artery inside [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage( + rand(30, 50), + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + +/** + * Removes organ from parent using any poking tool. + */ +/datum/surgery_step/internal/remove_organ + priority = 2 + duration = CLAMP_DURATION + + allowed_tools = list( + /obj/item/hemostat = 100, + /obj/item/wirecutters = 75, + /obj/item/material/knife = 75, + /obj/item/material/kitchen/utensil/fork = 20 + ) + +/datum/surgery_step/internal/remove_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + var/list/removable_organs = list() + var/obj/item/organ/external/parent_organ = target.get_organ(target_zone) + for(var/obj/item/organ/internal/O in parent_organ.implants) + if(O.status & ORGAN_CUT_AWAY) + removable_organs[O] = agjust_organ_image(O) + + var/obj/item/organ/preselected_organ = ..() + if(istype(preselected_organ)) + if(preselected_organ in removable_organs) + return preselected_organ + + return null + + var/obj/item/organ/selected_organ = show_radial_menu(user, target, removable_organs, require_near = TRUE) + if(!istype(selected_organ)) + return null + + return selected_organ + +/datum/surgery_step/internal/remove_organ/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts removing [target]'s [target_organ] with \the [tool].", + "You start removing [target]'s [target_organ] with \the [tool]." + ) + target.custom_pain("The pain in your [parent_organ] is living hell!", 100) + return ..() + +/datum/surgery_step/internal/remove_organ/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has removed [target]'s [target_organ] with \the [tool].", + "You have removed [target]'s [target_organ] with \the [tool]." + ) + + parent_organ.implants -= target_organ + target_organ.dropInto(target.loc) + if(!BP_IS_ROBOTIC(parent_organ)) + playsound(target.loc, 'sound/effects/squelch1.ogg', 15, 1) + else + playsound(target.loc, 'sound/items/Ratchet.ogg', 50, 1) + +/datum/surgery_step/internal/remove_organ/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, damaging [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, damaging [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage(20, used_weapon = tool) + +/** + * Puts organ inside its parent. + */ +/datum/surgery_step/internal/replace_organ + duration = ATTACH_DURATION + + allowed_tools = list( + /obj/item/organ/internal = 100 + ) + +/datum/surgery_step/internal/replace_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) + . = ..() + if(!.) + return + + var/obj/item/organ/target_organ = tool + if(!istype(target_organ)) + return FALSE + + if(BP_IS_ROBOTIC(parent_organ) && !BP_IS_ROBOTIC(target_organ)) + return FALSE // organic to robotic is bad + + if(!target.species) + CRASH("Target ([target]) of surgery [type] has no species!") + + if(target_organ.organ_tag == BP_POSIBRAIN && !target.species.has_organ[BP_POSIBRAIN]) + return FALSE // Posibrain to synth body is bad + + if(target_organ.damage > (target_organ.max_damage * 0.75)) + return FALSE // Too damageed + + if(target_organ.w_class > parent_organ.cavity_max_w_class) + return FALSE // Too big + + var/obj/item/organ/internal/O = target.internal_organs_by_name[target_organ.organ_tag] + if(O && (O.parent_organ == parent_organ.organ_tag || istype(target_organ, /obj/item/organ/internal/stack))) + return FALSE + + var/used_volume = 0 + for(var/obj/item/I in parent_organ.implants) + if(istype(I, /obj/item/implant)) + continue + + used_volume += I.get_storage_cost() + for(var/obj/item/I in parent_organ.internal_organs) + used_volume += I.get_storage_cost() + if((base_storage_capacity(parent_organ.cavity_max_w_class) + parent_organ.internal_organs_size) < used_volume + target_organ.get_storage_cost()) + return FALSE // There's no space... + + return TRUE + +/datum/surgery_step/internal/replace_organ/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return TRUE + +/datum/surgery_step/internal/replace_organ/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts transplanting \the [tool] into [target]'s [parent_organ].", + "You start transplanting \the [tool] into [target]'s [parent_organ]." + ) + target.custom_pain("Someone's rooting around in your [parent_organ]!", 100) + return ..() + +/datum/surgery_step/internal/replace_organ/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has transplanted \the [tool] into [target]'s [parent_organ].", + "You have transplanted \the [tool] into [target]'s [parent_organ]." + ) + var/obj/item/organ/O = tool + if(!istype(O)) + return + + user.drop(O, target) + target.update_deformities() + parent_organ.implants |= O + if(!(O.status & ORGAN_CUT_AWAY)) + log_debug("[user] ([user.ckey]) replaced organ [O], which didn't have ORGAN_CUT_AWAY set, in [target] ([target.ckey])") + O.status |= ORGAN_CUT_AWAY + + playsound(target.loc, 'sound/effects/squelch1.ogg', 15, TRUE) + +/datum/surgery_step/internal/replace_organ/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, damaging \the [tool]!", + "Your hand slips, damaging \the [tool]!" + ) + var/obj/item/organ/internal/I = tool + if(!istype(tool)) + return + + I.take_internal_damage(rand(3, 5), FALSE) + +/** + * Drefault organ fixing step, does nothing, has overrides. + */ +/datum/surgery_step/internal/fix_organ + duration = ORGAN_FIX_DURATION + +/datum/surgery_step/internal/fix_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) + return (istype(parent_organ) && !BP_IS_ROBOTIC(parent_organ)) + +/datum/surgery_step/internal/fix_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + var/list/damaged_organs = list() + var/obj/item/organ/external/parent_organ = target.get_organ(target_zone) + for(var/obj/item/organ/internal/I in target.internal_organs) + if(BP_IS_ROBOTIC(I)) + continue + + if(I.damage <= 0) + continue + + if(I.status & ORGAN_CUT_AWAY) + continue + + if(I.parent_organ != parent_organ.organ_tag) + continue + + if(!I.surface_accessible && parent_organ.open() < (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED)) + continue + + damaged_organs[I] = agjust_organ_image(I) + + var/obj/item/organ/internal/preselected_organ = ..() + if(istype(preselected_organ)) + if(preselected_organ in damaged_organs) + return preselected_organ + + return null + + var/obj/item/organ/internal/selected_organ = show_radial_menu(user, target, damaged_organs, require_near = TRUE) + if(!istype(selected_organ)) + return null + + return selected_organ + +/datum/surgery_step/internal/fix_organ/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(!istype(target_organ, /obj/item/organ/internal)) + return FALSE + + if(!target_organ.can_recover()) + return FALSE // Destroyed organ + + return !!target_organ.damage + +/** + * Fixes chosen organ using organ fixer. + */ +/datum/surgery_step/internal/fix_organ/default/default + duration = ORGAN_FIX_DURATION + + allowed_tools = list( + /obj/item/organfixer/standard = 100 + ) + +/datum/surgery_step/internal/fix_organ/default/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + var/obj/item/organfixer/organ_fixer = tool + if(!istype(organ_fixer)) + return FALSE + + if(!. && !organ_fixer.emagged) + return FALSE + + return organ_fixer.gel_amt > 0 + +/datum/surgery_step/internal/fix_organ/default/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts repairing [target]'s [target_organ] with \the [tool].", + "You start repairing [target]'s [target_organ] with \the [tool]." + ) + target.custom_pain( + "Something in your [target_organ] is causing you a lot of pain!", + 50 + ) + return ..() + +/datum/surgery_step/internal/fix_organ/default/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/organ/internal/internal_organ = target_organ + if(!istype(internal_organ)) + return + + var/obj/item/organfixer/organ_fixer = tool + if(organ_fixer.gel_amt == 0) + return + + if(organ_fixer.emagged) + announce_success(user, + "[user]'s hand slips, getting mess and tearing the inside of [target]'s [internal_organ] with \the [organ_fixer]!", + "Something goes wrong and \the [organ_fixer] shreds [target]'s [internal_organ] before you have a chance to react!" + ) + target.custom_pain( + "Your [internal_organ] feels like it's getting torn apart!", + 150 + ) + target.adjustToxLoss(30) + parent_organ.take_external_damage(10, 0, (DAM_SHARP|DAM_EDGE), used_weapon = organ_fixer) + internal_organ.take_internal_damage((parent_organ.max_damage - parent_organ.damage), 0) + return + + announce_success(user, + "[user] repairs [target]'s [internal_organ] with [organ_fixer].", + "You repair [target]'s [internal_organ] with [organ_fixer]." + ) + + if((internal_organ.status & ORGAN_DEAD) && internal_organ.can_recover()) + internal_organ.status &= ~ORGAN_DEAD + + internal_organ.damage = 0 + target.update_body(TRUE) + +/datum/surgery_step/internal/fix_organ/default/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/organ/internal/internal_organ = target_organ + if(!istype(internal_organ)) + return + + announce_failure(user, + "[user]'s hand slips, getting mess and tearing the inside of [target]'s [internal_organ] with \the [tool]!", + "Your hand slips, getting mess and tearing the inside of [target]'s [internal_organ] with \the [tool]!" + ) + + target.adjustToxLoss(10) + parent_organ.take_external_damage(5, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) + + if(internal_organ.damage > 0) + internal_organ.take_internal_damage(5, 0) + +/** + * Ghetto way to fix one chosen organ inside targeted zone. + */ +/datum/surgery_step/internal/fix_organ/ghetto + duration = ORGAN_FIX_DURATION * 1.75 + + allowed_tools = list( + /obj/item/stack/medical/advanced/bruise_pack= 67, + /obj/item/stack/medical/bruise_pack = 34, + /obj/item/tape_roll = 20 + ) + +/datum/surgery_step/internal/fix_organ/ghetto/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(!istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) + return FALSE + + if(!istype(tool, /obj/item/stack/medical/bruise_pack)) + return FALSE + + var/obj/item/stack/medical/M = tool + if(M.amount < 1) + return FALSE // Nothing left + + return TRUE + +/datum/surgery_step/internal/fix_organ/ghetto/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/tool_name = "\the [tool]" + if(istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) + tool_name = "regenerative membrane" + else if(istype(tool, /obj/item/stack/medical/bruise_pack)) + tool_name = "the bandaid" + + announce_preop(user, + "[user] starts treating damage to [target]'s [target_organ] with \the [tool_name].", + "You start treating damage to [target]'s [target_organ] with \the [tool_name]." + ) + target.custom_pain("The pain in your [parent_organ] is living hell!", 100) + return ..() + +/datum/surgery_step/internal/fix_organ/ghetto/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/organ/internal/internal_organ = target_organ + if(!istype(internal_organ)) + return + + var/tool_name = "\the [tool]" + if(istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) + tool_name = "regenerative membrane" + else if(istype(tool, /obj/item/stack/medical/bruise_pack)) + tool_name = "the bandaid" + + if((internal_organ.status & ORGAN_DEAD) && internal_organ.can_recover()) + announce_success(user, + "[user] treats damage to [target]'s [internal_organ] with [tool_name], though it needs to be recovered further.", + "You treat damage to [target]'s [internal_organ] with [tool_name], though it needs to be recovered further." + ) + else + announce_success(user, + "[user] treats damage to [target]'s [internal_organ] with [tool_name].", + "You treat damage to [target]'s [internal_organ] with [tool_name]." + ) + + var/obj/item/stack/medical/M = tool + M.use(1) + + internal_organ.damage = 0 + target.update_body(TRUE) + +/datum/surgery_step/internal/fix_organ/ghetto/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, getting mess and tearing the inside of [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, getting mess and tearing the inside of [target]'s [parent_organ] with \the [tool]!" + ) + + var/dam_amt = 2 + if(istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) + target.adjustToxLoss(5) + else + dam_amt = 5 + target.adjustToxLoss(10) + parent_organ.take_external_damage(dam_amt, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) + + for(var/obj/item/organ/internal/I in parent_organ.internal_organs) + if(I.damage > 0 && !BP_IS_ROBOTIC(I)) + I.take_internal_damage(dam_amt, 0) + +/** + * Fixes all damaged organs inside targeted zone. + */ +/datum/surgery_step/internal/fix_organ/multiple + allowed_tools = list( + /obj/item/organfixer/advanced = 100 + ) + +/datum/surgery_step/internal/fix_organ/multiple/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) + . = ..() + if(!.) + return + + var/obj/item/organfixer/organ_fixer = tool + if(!istype(organ_fixer)) + return FALSE + + if(organ_fixer.gel_amt == 0) + return FALSE + + for(var/obj/item/organ/internal/I in parent_organ.internal_organs) + if(BP_IS_ROBOTIC(I)) + continue + + if(I.damage <= 0) + continue + + if(I.status & ORGAN_CUT_AWAY) + continue + + if(I.parent_organ != parent_organ.organ_tag) + continue + + if(!I.surface_accessible && parent_organ.open() < (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED)) + continue + + return TRUE + + return FALSE + +/datum/surgery_step/internal/fix_organ/multiple/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + return null + +/datum/surgery_step/internal/fix_organ/multiple/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return TRUE + +/datum/surgery_step/internal/fix_organ/multiple/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts treating damage inside [target]'s [parent_organ] with \the [tool].", + "You start treating damage to inside [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain("The pain in your [parent_organ] is living hell!", 100) + return ..() + +/datum/surgery_step/internal/fix_organ/multiple/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/organfixer/organ_fixer = tool + if(!istype(organ_fixer)) + return + + if(organ_fixer.emagged) + announce_success(user, + "[user]'s hand slips, getting mess and tearing the inside of [target]'s [parent_organ] with \the [organ_fixer]!", + "Something goes wrong and \the [organ_fixer] shreds everything inside [target]'s [parent_organ] before you have a chance to react!" + ) + target.custom_pain( + "Your whole [parent_organ] feels like it's getting torn apart!", + 150 + ) + target.adjustToxLoss(30) + parent_organ.take_external_damage(15, 0, (DAM_SHARP|DAM_EDGE), used_weapon = organ_fixer) + for(var/obj/item/organ/internal/I in parent_organ.internal_organs) + if(I && (I.surface_accessible || parent_organ.open() >= (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED))) + I.take_internal_damage((parent_organ.max_damage - parent_organ.damage), 0) + return + + for(var/obj/item/organ/internal/I in parent_organ.internal_organs) + if(I.damage > 0 && !BP_IS_ROBOTIC(I) && (I.surface_accessible || parent_organ.open() >= (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED))) + if(organ_fixer.gel_amt == 0) + return + + if((I.status & ORGAN_DEAD) && !I.can_recover()) + continue + + if(I.status & ORGAN_DEAD) + I.status &= ~ORGAN_DEAD + + if(organ_fixer.gel_amt > 0) + organ_fixer.gel_amt-- + + I.owner.update_body(TRUE) + I.damage = 0 + + announce_success(user, + "[user] repairs organs in [target]'s [parent_organ] with \the [organ_fixer].", + "You repair organs in [target]'s [parent_organ] with \the [organ_fixer]." + ) + +/datum/surgery_step/internal/fix_organ/multiple/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, getting mess and tearing the inside of [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, getting mess and tearing the inside of [target]'s [parent_organ] with \the [tool]!" + ) + target.adjustToxLoss(10) + parent_organ.take_external_damage(5, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) + for(var/obj/item/organ/internal/I in parent_organ.internal_organs) + if(I.damage > 0 && !BP_IS_ROBOTIC(I) && (I.surface_accessible || parent_organ.open() >= (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED))) + I.take_internal_damage(5, 0) + +/** + * Treats dead organs. + */ +/datum/surgery_step/internal/treat_necrosis + blood_level = 0 + priority = 2 + duration = TREAT_NECROSIS_DURATION + + allowed_tools = list( + /obj/item/reagent_containers/dropper = 100, \ + /obj/item/reagent_containers/vessel/bottle/chemical = 75, \ + /obj/item/reagent_containers/vessel/beaker = 75, \ + /obj/item/reagent_containers/spray = 50, \ + /obj/item/reagent_containers/vessel/bucket = 50 + ) + +/datum/surgery_step/internal/treat_necrosis/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) + return (..() && !BP_IS_ROBOTIC(parent_organ)) + +/datum/surgery_step/internal/treat_necrosis/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + var/list/dead_organs = list() + var/obj/item/organ/external/parent_organ = target.get_organ(target_zone) + for(var/obj/item/organ/internal/O in target.internal_organs) + if(BP_IS_ROBOTIC(O)) + continue + + if(!(O.status & ORGAN_CUT_AWAY) && (O.status & ORGAN_DEAD) && O.parent_organ == parent_organ.organ_tag) + dead_organs[O] = agjust_organ_image(O) + + var/obj/item/organ/internal/preselected_organ = ..() + if(istype(preselected_organ)) + if(preselected_organ in dead_organs) + return preselected_organ + + return null + + var/obj/item/organ/internal/selected_organ = show_radial_menu(user, target, dead_organs, require_near = TRUE) + if(!istype(selected_organ)) + return null + + return selected_organ + +/datum/surgery_step/internal/treat_necrosis/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + var/obj/item/reagent_containers/container = tool + if(!istype(container)) + return FALSE + + if(!container.reagents.has_reagent(/datum/reagent/peridaxon)) + return FALSE + + if(!target_organ.can_recover() && istype(target_organ, /obj/item/organ/internal/cerebrum/brain)) + return FALSE + + return TRUE + +/datum/surgery_step/internal/treat_necrosis/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + user.visible_message( + "[user] starts applying medication to the affected tissue in [target]'s [parent_organ] with \the [tool].", + "You start applying medication to the affected tissue in [target]'s [parent_organ] with \the [tool]." + ) + + target.custom_pain( + "Something in your [parent_organ] is causing you a lot of pain!", + 50 + ) + return ..() + +/datum/surgery_step/internal/treat_necrosis/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/reagent_containers/container = tool + if(!istype(container)) + return + + var/amount = container.amount_per_transfer_from_this + var/datum/reagents/temp_reagents = new(amount, GLOB.temp_reagents_holder) + container.reagents.trans_to_holder(temp_reagents, amount) + + var/rejuvenate = temp_reagents.has_reagent(/datum/reagent/peridaxon) + + var/trans = temp_reagents.trans_to_mob(target, temp_reagents.total_volume, CHEM_BLOOD) + qdel(temp_reagents) + if(trans <= 0) + return + + if(rejuvenate) + if(target_organ.can_recover()) + target_organ.damage = 0 + target_organ.status &= ~ORGAN_DEAD + else + target_organ.damage = target_organ.min_broken_damage + target_organ.death_time = 0 + target.update_body(TRUE) + + announce_success(user, + "[user] applies [trans] unit\s of the solution to affected tissue in [target]'s [parent_organ]", + "You apply [trans] unit\s of the solution to affected tissue in [target]'s [parent_organ] with \the [tool]." + ) + + +/datum/surgery_step/internal/treat_necrosis/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/reagent_containers/container = tool + if(!istype(container)) + return + + announce_failure(user, + "[user]'s hand slips, applying solution to the wrong place in [target]'s [parent_organ] with the [tool]!", + "Your hand slips, applying solution to the wrong place in [target]'s [parent_organ] with the [tool]!" + ) + container.reagents.trans_to_mob(target, container.amount_per_transfer_from_this, CHEM_BLOOD) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm deleted file mode 100644 index bb24a066228..00000000000 --- a/code/modules/surgery/organs_internal.dm +++ /dev/null @@ -1,787 +0,0 @@ -//Procedures in this file: internal organ surgery, removal, transplants -////////////////////////////////////////////////////////////////// -// INTERNAL ORGANS // -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal - priority = 2 - can_infect = 1 - blood_level = 1 - shock_level = 40 - delicate = 1 - var/obj/item/organ/preselected_organ - var/ignore_tool = FALSE - -/datum/surgery_step/internal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return FALSE - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) - return FALSE - if(BP_IS_ROBOTIC(affected)) - return affected.hatch_state == HATCH_OPENED - else - return affected.open() == (affected.encased ? SURGERY_ENCASED : SURGERY_RETRACTED) - -/datum/surgery_step/internal/proc/tweak_image(obj/item/organ/I) - var/image/img = image(icon = I.icon, icon_state = I.icon_state) - img.overlays = I.overlays - img.pixel_y = -5 - return img - -////////////////////////////////////////////////////////////////// -// Single organ mending surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/fix_organ - allowed_tools = list( - /obj/item/organfixer/standard = 100 - ) - - duration = ORGAN_FIX_DURATION - -/datum/surgery_step/internal/fix_organ/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organfixer/O = tool - if(!istype(O)) - return FALSE - if(!..()) - return FALSE - if(O.gel_amt == 0) - to_chat(user, SPAN("warning", "\The [O] is empty!")) - return SURGERY_FAILURE - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - if(BP_IS_ROBOTIC(affected)) - return FALSE - - target.op_stage.current_organ = null - - var/list/damaged_organs = list() - for(var/obj/item/organ/internal/I in target.internal_organs) - if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == affected.organ_tag && !BP_IS_ROBOTIC(I)) - var/image/img = tweak_image(I) - damaged_organs[I] = img - - var/obj/item/organ/surgery_organ = preselected_organ - - if(preselected_organ && !(preselected_organ in damaged_organs)) - return SURGERY_FAILURE - - if(!preselected_organ) - surgery_organ = show_radial_menu(user, target, damaged_organs, require_near = TRUE) - - preselected_organ = null - - if(!surgery_organ || (!ignore_tool && (user.get_active_hand().return_item() != tool))) - return FALSE - if(!surgery_organ.can_recover()) - to_chat(user, SPAN("notice", "The [surgery_organ.name] is destroyed and can't be saved.")) - return SURGERY_FAILURE - if(!surgery_organ.damage && !O.emagged) - to_chat(user, SPAN("notice", "The [surgery_organ.name] is intact and doesn't require any healing.")) - return SURGERY_FAILURE - - target.op_stage.current_organ = surgery_organ - return TRUE - -/datum/surgery_step/internal/fix_organ/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) - if(!affected || affected.open() < 2) - return - user.visible_message("[user] starts repairing [target]'s [target.op_stage.current_organ] with \the [tool]." , \ - "You start repairing [target]'s [target.op_stage.current_organ] with \the [tool].") - - target.custom_pain("Something in your [target.op_stage.current_organ] is causing you a lot of pain!",50) - ..() - -/datum/surgery_step/internal/fix_organ/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/internal/affected = target.op_stage.current_organ - var/obj/item/organfixer/O = tool - if(O.gel_amt != 0) - if(!O.emagged) - if(affected && affected.damage > 0 && !BP_IS_ROBOTIC(affected) && (affected.surface_accessible || target.get_organ(target_zone).open() >= (target.get_organ(target_zone).encased ? SURGERY_ENCASED : SURGERY_RETRACTED))) - user.visible_message(SPAN("notice", "[user] repairs [target]'s [affected.name] with [O]."), \ - SPAN("notice", "You repair [target]'s [affected.name] with [O].")) - affected.damage = 0 - if(affected.status & ORGAN_DEAD && affected.can_recover()) - affected.status &= ~ORGAN_DEAD - affected.owner.update_body(1) - else - user.visible_message(SPAN("warning", "[user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [O]!"), \ - SPAN("warning", "Something goes wrong and \the [O] shreds [target]'s [affected.name] before you have a chance to react!")) - - target.custom_pain("Your [target.op_stage.current_organ] feels like it's getting torn apart!",150) - target.adjustToxLoss(30) - target.get_organ(target_zone).take_external_damage(10, 0, (DAM_SHARP|DAM_EDGE), used_weapon = O) - affected.take_internal_damage((affected.max_damage - affected.damage), 0) - if(O.gel_amt_max != -1) - O.gel_amt-- - else - to_chat(user, SPAN("warning", "\The [O] is empty!")) - target.op_stage.current_organ = null - -/datum/surgery_step/internal/fix_organ/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return - var/obj/item/organ/internal/affected = target.op_stage.current_organ - - user.visible_message(SPAN("warning", "[user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!"), \ - SPAN("warning", "Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!")) - - target.adjustToxLoss(10) - target.get_organ(target_zone).take_external_damage(5, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - - if(affected && affected.damage > 0 && !BP_IS_ROBOTIC(affected) && (affected.surface_accessible || target.get_organ(target_zone).open() >= (target.get_organ(target_zone).encased ? 3 : 2))) - affected.take_internal_damage(5, 0) - target.op_stage.current_organ = null - - -////////////////////////////////////////////////////////////////// -// Multiple organs mending surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/fix_organ_multiple - allowed_tools = list( - /obj/item/organfixer/advanced = 100 - ) - - duration = ORGAN_FIX_DURATION - -/datum/surgery_step/internal/fix_organ_multiple/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organfixer/O = tool - if(!istype(O)) - return FALSE - if(!..()) - return FALSE - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(BP_IS_ROBOTIC(affected)) - return FALSE - if(O.gel_amt == 0) - to_chat(user, SPAN("warning", "\The [O] is empty!")) - return SURGERY_FAILURE - if(O.emagged == 1) // We can shred 'em even if they have no damaged internals - return TRUE - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I.damage > 0) - if(I.surface_accessible) - return TRUE - if(affected.open() >= (affected.encased ? SURGERY_ENCASED : SURGERY_RETRACTED)) - return TRUE - return FALSE - -/datum/surgery_step/internal/fix_organ_multiple/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return - var/obj/item/organfixer/O = tool - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected || affected.open() < 2) - return - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I && (I.damage > 0 || O.emagged == 1) && !BP_IS_ROBOTIC(I) && (!(I.status & ORGAN_DEAD) || I.can_recover()) && (I.surface_accessible || affected.open() >= (affected.encased ? 3 : 2))) - user.visible_message("[user] starts treating damage to [target]'s [I.name] with \the [tool].", \ - "You start treating damage to [target]'s [I.name] with \the [tool]." ) - - target.custom_pain("The pain in your [affected.name] is living hell!",100) - ..() - -/datum/surgery_step/internal/fix_organ_multiple/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return - var/obj/item/organfixer/O = tool - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected || affected.open() < 2) - return - if(!O.emagged) - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I && I.damage > 0 && !BP_IS_ROBOTIC(I) && (I.surface_accessible || affected.open() >= (affected.encased ? SURGERY_ENCASED : SURGERY_RETRACTED))) - if(O.gel_amt == 0) - to_chat(user, SPAN("warning", "\The [O] runs out of gel!")) - return FALSE - if((I.status & ORGAN_DEAD) && !I.can_recover()) - to_chat(user, SPAN("notice", "[target]'s [I.name] is destroyed and can't be fixed with \the [O].")) - continue - user.visible_message(SPAN("notice", "[user] repairs [target]'s [I.name] with \the [O]."), \ - SPAN("notice", "You repair [target]'s [I.name] with \the [O].")) - I.damage = 0 - if((I.status & ORGAN_DEAD) && I.can_recover()) - I.status &= ~ORGAN_DEAD - I.owner.update_body(1) - if(O.gel_amt_max != -1) - O.gel_amt-- - else - user.visible_message(SPAN("warning", "[user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [O]!"), \ - SPAN("warning", "Something goes wrong and \the [O] shreds everything inside [target]'s [affected.name] before you have a chance to react!")) - - target.custom_pain("Your whole [affected] feels like it's getting torn apart!",150) - target.adjustToxLoss(30) - affected.take_external_damage(15, 0, (DAM_SHARP|DAM_EDGE), used_weapon = O) - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I && (I.surface_accessible || affected.open() >= (affected.encased ? SURGERY_ENCASED : SURGERY_RETRACTED))) - I.take_internal_damage((affected.max_damage - affected.damage), 0) - -/datum/surgery_step/internal/fix_organ_multiple/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(SPAN("warning", "[user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!"), \ - SPAN("warning", "Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!")) - target.adjustToxLoss(10) - affected.take_external_damage(5, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I && I.damage > 0 && !BP_IS_ROBOTIC(I) && (I.surface_accessible || affected.open() >= (affected.encased ? 3 : 2))) - I.take_internal_damage(5, 0) - -////////////////////////////////////////////////////////////////// -// Ghetto organs mending surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/fix_organ_ghetto - allowed_tools = list( - /obj/item/stack/medical/advanced/bruise_pack= 67, \ - /obj/item/stack/medical/bruise_pack = 34, \ - /obj/item/tape_roll = 20 - ) - - duration = ORGAN_FIX_DURATION * 1.75 - -/datum/surgery_step/internal/fix_organ_ghetto/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(BP_IS_ROBOTIC(affected)) - return FALSE - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - if(istype(tool, /obj/item/stack/medical/advanced/bruise_pack) || istype(tool, /obj/item/stack/medical/bruise_pack)) - var/obj/item/stack/medical/M = tool - if(M.amount < 1) - to_chat(user, SPAN("warning", "\The [M] is empty!")) - return SURGERY_FAILURE - - var/list/damaged_organs = list() - for(var/obj/item/organ/internal/I in target.internal_organs) - if(I && !(I.status & ORGAN_CUT_AWAY) && I.parent_organ == affected.organ_tag && !BP_IS_ROBOTIC(I)) - var/image/img = tweak_image(I) - damaged_organs[I] = img - - var/obj/item/organ/surgery_organ = preselected_organ - - if(preselected_organ && !(preselected_organ in damaged_organs)) - return SURGERY_FAILURE - - if(!preselected_organ) - surgery_organ = show_radial_menu(user, target, damaged_organs, require_near = TRUE) - - preselected_organ = null - - if(!surgery_organ || (!ignore_tool && (user.get_active_hand().return_item() != tool))) - return FALSE - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - if(!surgery_organ.can_recover()) - to_chat(user, SPAN("notice", "The [surgery_organ.name] is destroyed and can't be saved.")) - return SURGERY_FAILURE - if(!surgery_organ.damage) - to_chat(user, SPAN("notice", "The [surgery_organ.name] is intact and doesn't require any healing.")) - return SURGERY_FAILURE - - target.op_stage.current_organ = surgery_organ - return FALSE - -/datum/surgery_step/internal/fix_organ_ghetto/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/tool_name = "\the [tool]" - if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) - tool_name = "regenerative membrane" - else if (istype(tool, /obj/item/stack/medical/bruise_pack)) - tool_name = "the bandaid" - - if (!hasorgans(target)) - return - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected || affected.open() < 2) - return - user.visible_message("[user] starts treating damage to [target]'s [target.op_stage.current_organ] with \the [tool_name]." , \ - "You start treating damage to [target]'s [target.op_stage.current_organ] with \the [tool_name].") - target.custom_pain("The pain in your [affected.name] is living hell!",100) - ..() - -/datum/surgery_step/internal/fix_organ_ghetto/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return - var/tool_name = "\the [tool]" - if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) - tool_name = "regenerative membrane" - if (istype(tool, /obj/item/stack/medical/bruise_pack)) - tool_name = "the bandaid" - var/obj/item/organ/internal/affected = target.op_stage.current_organ - if(affected && affected.damage > 0 && !BP_IS_ROBOTIC(affected) && (affected.surface_accessible || target.get_organ(target_zone).open() >= (target.get_organ(target_zone).encased ? SURGERY_ENCASED : SURGERY_RETRACTED))) - if(affected.status & ORGAN_DEAD && affected.can_recover()) - user.visible_message(SPAN("notice", "[user] treats damage to [target]'s [affected.name] with [tool_name], though it needs to be recovered further."), \ - SPAN("notice", "You treat damage to [target]'s [affected.name] with [tool_name], though it needs to be recovered further.")) - else - user.visible_message(SPAN("notice", "[user] treats damage to [target]'s [affected.name] with [tool_name]."), \ - SPAN("notice", "You treat damage to [target]'s [affected.name] with [tool_name].")) - if(istype(tool, /obj/item/stack/medical/advanced/bruise_pack) || istype(tool, /obj/item/stack/medical/bruise_pack)) - var/obj/item/stack/medical/M = tool - M.use(1) - affected.damage = 0 - affected.owner.update_body(1) - target.op_stage.current_organ = null - -/datum/surgery_step/internal/fix_organ_ghetto/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(SPAN("warning", "[user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!"), \ - SPAN("warning", "Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!")) - var/dam_amt = 2 - - if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) - target.adjustToxLoss(5) - - else - dam_amt = 5 - target.adjustToxLoss(10) - affected.take_external_damage(dam_amt, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I && I.damage > 0 && !BP_IS_ROBOTIC(I) && (I.surface_accessible || affected.open() >= (affected.encased ? 3 : 2))) - I.take_internal_damage(dam_amt, 0) - -////////////////////////////////////////////////////////////////// -// Organ detatchment surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/detatch_organ - - allowed_tools = list( - /obj/item/scalpel = 100, \ - /obj/item/material/knife = 75, \ - /obj/item/material/kitchen/utensil/knife = 75, \ - /obj/item/material/shard = 50 - ) - - duration = CUT_DURATION * 1.75 - -/datum/surgery_step/internal/detatch_organ/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(BP_IS_ROBOTIC(affected)) - return FALSE - - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - - var/list/attached_organs = list() - for(var/obj/item/organ/organ in target.internal_organs) - if(organ && !(organ.status & ORGAN_CUT_AWAY) && organ.parent_organ == target_zone) - var/image/img = tweak_image(organ) - attached_organs[organ] = img - - var/obj/item/organ/surgery_organ = preselected_organ - - if(preselected_organ && !(preselected_organ in attached_organs)) - return SURGERY_FAILURE - - if(!preselected_organ) - surgery_organ = show_radial_menu(user, target, attached_organs, require_near = TRUE) - - preselected_organ = null - - if(!surgery_organ || (!ignore_tool && (user.get_active_hand().return_item() != tool))) - return FALSE - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - - target.op_stage.current_organ = surgery_organ - - return ..() && surgery_organ - -/datum/surgery_step/internal/detatch_organ/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts to separate [target]'s [target.op_stage.current_organ] with \the [tool].", \ - "You start to separate [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/detatch_organ/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message(SPAN("notice", "[user] has separated [target]'s [target.op_stage.current_organ] with \the [tool].") , \ - SPAN("notice", "You have separated [target]'s [target.op_stage.current_organ] with \the [tool].")) - - var/obj/item/organ/I = target.op_stage.current_organ - if(istype(I)) - I.cut_away(I.owner) - -/datum/surgery_step/internal/detatch_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(SPAN("warning", "[user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!"), \ - SPAN("warning", "Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!")) - affected.take_external_damage(rand(30,50), 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// Organ removal surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/remove_organ - priority = 2 - allowed_tools = list( - /obj/item/hemostat = 100, \ - /obj/item/wirecutters = 75, \ - /obj/item/material/knife = 75, \ - /obj/item/material/kitchen/utensil/fork = 20 - ) - - duration = CLAMP_DURATION - -/datum/surgery_step/internal/remove_organ/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!..()) - return FALSE - - target.op_stage.current_organ = null - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - - var/list/removable_organs = list() - for(var/obj/item/organ/internal/I in affected.implants) - if(I.status & ORGAN_CUT_AWAY) - var/image/img = tweak_image(I) - removable_organs[I] = img - - var/obj/item/organ/surgery_organ = preselected_organ - - if(preselected_organ && !(preselected_organ in removable_organs)) - return SURGERY_FAILURE - - if(!preselected_organ) - surgery_organ = show_radial_menu(user, target, removable_organs, require_near = TRUE) - - preselected_organ = null - - if(!surgery_organ || (!ignore_tool && (user.get_active_hand().return_item() != tool))) - return FALSE - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - - target.op_stage.current_organ = surgery_organ - 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) - 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("The pain in your [affected.name] is living hell!",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(SPAN("notice", "[user] has removed [target]'s [target.op_stage.current_organ] with \the [tool]."), \ - SPAN("notice", "You have removed [target]'s [target.op_stage.current_organ] with \the [tool].")) - - // Extract the organ! - var/obj/item/organ/O = target.op_stage.current_organ - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(istype(O) && istype(affected)) - affected.implants -= O - O.dropInto(target.loc) - target.op_stage.current_organ = null - if(!BP_IS_ROBOTIC(affected)) - playsound(target.loc, 'sound/effects/squelch1.ogg', 15, 1) - else - playsound(target.loc, 'sound/items/Ratchet.ogg', 50, 1) - -/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) - user.visible_message(SPAN("warning", "[user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!"), \ - SPAN("warning", "Your hand slips, damaging [target]'s [affected.name] with \the [tool]!")) - affected.take_external_damage(20, used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// Organ inserting surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/replace_organ - allowed_tools = list( - /obj/item/organ = 100 - ) - - duration = ATTACH_DURATION - -/datum/surgery_step/internal/replace_organ/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!..()) - return FALSE - - var/obj/item/organ/internal/O = tool - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) - return FALSE - - if(!istype(O)) - return FALSE - - if(BP_IS_ROBOTIC(affected) && !BP_IS_ROBOTIC(O)) - to_chat(user, SPAN("danger", "You cannot install a naked organ into a robotic body.")) - return SURGERY_FAILURE - - if(!target.species) - CRASH("Target ([target]) of surgery [type] has no species!") - - var/o_is = (O.gender == PLURAL) ? "are" : "is" - var/o_a = (O.gender == PLURAL) ? "" : "a " - - if(O.organ_tag == BP_POSIBRAIN && !target.species.has_organ[BP_POSIBRAIN]) - to_chat(user, SPAN("warning", "There's no place in [target] to fit \the [O.organ_tag].")) - return SURGERY_FAILURE - - if(O.damage > (O.max_damage * 0.75)) - to_chat(user, SPAN("warning", "\The [O.name] [o_is] in no state to be transplanted.")) - return SURGERY_FAILURE - if(O.w_class > affected.cavity_max_w_class) - to_chat(user, SPAN("warning", "\The [O.name] [o_is] too big for [affected.cavity_name] cavity!")) - return SURGERY_FAILURE - - var/obj/item/organ/internal/I = target.internal_organs_by_name[O.organ_tag] - if(I && (I.parent_organ == affected.organ_tag || istype(O, /obj/item/organ/internal/stack))) - to_chat(user, SPAN("warning", "\The [target] already has [o_a][O.name].")) - return SURGERY_FAILURE - - var/used_volume = 0 - for(var/obj/item/implant in affected.implants) - if(istype(implant, /obj/item/implant)) - continue - used_volume += implant.get_storage_cost() - for(var/obj/item/organ in affected.internal_organs) - used_volume += organ.get_storage_cost() - if((base_storage_capacity(affected.cavity_max_w_class) + affected.internal_organs_size) < used_volume + O.get_storage_cost()) - to_chat(user, SPAN("warning", "There isn't enough space left in [affected.name]")) - return SURGERY_FAILURE - - return ..() - -/datum/surgery_step/internal/replace_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) - user.visible_message("[user] starts transplanting \the [tool] into [target]'s [affected.name].", \ - "You start transplanting \the [tool] into [target]'s [affected.name].") - target.custom_pain("Someone's rooting around in your [affected.name]!",100) - ..() - -/datum/surgery_step/internal/replace_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) - user.visible_message(SPAN("notice", "[user] has transplanted \the [tool] into [target]'s [affected.name]."), \ - SPAN("notice", "You have transplanted \the [tool] into [target]'s [affected.name].")) - var/obj/item/organ/O = tool - if(istype(O)) - user.drop(O, target) - target.update_deformities() - affected.implants |= O //move the organ into the patient. The organ is properly reattached in the next step - if(!(O.status & ORGAN_CUT_AWAY)) - log_debug("[user] ([user.ckey]) replaced organ [O], which didn't have ORGAN_CUT_AWAY set, in [target] ([target.ckey])") - O.status |= ORGAN_CUT_AWAY - - playsound(target.loc, 'sound/effects/squelch1.ogg', 15, 1) - -/datum/surgery_step/internal/replace_organ/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message(SPAN("warning", "[user]'s hand slips, damaging \the [tool]!"), \ - SPAN("warning", "Your hand slips, damaging \the [tool]!")) - var/obj/item/organ/internal/I = tool - if(istype(I)) - I.take_internal_damage(rand(3,5), 0) - -////////////////////////////////////////////////////////////////// -// Organ inserting surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/attach_organ - allowed_tools = list( - /obj/item/FixOVein = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/tape_roll = 50 - ) - - duration = CONNECT_DURATION - -/datum/surgery_step/internal/attach_organ/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!..()) - return FALSE - - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return FALSE - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(BP_IS_ROBOTIC(affected)) - // robotic attachment handled via screwdriver - return FALSE - - var/list/attachable_organs = list() - for(var/obj/item/organ/I in affected.implants) - if(I && (I.status & ORGAN_CUT_AWAY)) - var/image/img = tweak_image(I) - attachable_organs[I] = img - - var/obj/item/organ/surgery_organ = preselected_organ - - if(preselected_organ && !(preselected_organ in attachable_organs)) - return SURGERY_FAILURE - - if(!preselected_organ) - surgery_organ = show_radial_menu(user, target, attachable_organs, require_near = TRUE) - - preselected_organ = null - - if(!surgery_organ || (!ignore_tool && (user.get_active_hand().return_item() != tool))) - return FALSE - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - if(surgery_organ.parent_organ != affected.organ_tag) - to_chat(user, SPAN("warning", "You can't find anywhere to attach [surgery_organ] to!")) - return SURGERY_FAILURE - - target.op_stage.current_organ = surgery_organ - return ..() - -/datum/surgery_step/internal/attach_organ/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].", \ - "You start reattaching [target]'s [target.op_stage.current_organ] with \the [tool].") - target.custom_pain("Someone's digging needles into your [target.op_stage.current_organ]!",100) - ..() - -/datum/surgery_step/internal/attach_organ/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message(SPAN("notice", "[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.op_stage.current_organ - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(istype(I) && I.parent_organ == target_zone && affected && (I in affected.implants)) - I.status &= ~ORGAN_CUT_AWAY //apply fixovein - affected.implants -= I - I.replaced(target, affected) - target.update_deformities() - -/datum/surgery_step/internal/attach_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(SPAN("warning", "[user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!"), \ - SPAN("warning", "Your hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!")) - affected.take_external_damage(20, used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// Peridaxon destroyed organ restoration surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/internal/treat_necrosis - priority = 2 - allowed_tools = list( - /obj/item/reagent_containers/dropper = 100, \ - /obj/item/reagent_containers/vessel/bottle/chemical = 75, \ - /obj/item/reagent_containers/vessel/beaker = 75, \ - /obj/item/reagent_containers/spray = 50, \ - /obj/item/reagent_containers/vessel/bucket = 50 - ) - - can_infect = 0 - blood_level = 0 - - duration = ORGAN_FIX_DURATION * 0.75 - -/datum/surgery_step/internal/treat_necrosis/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/reagent_containers/container = tool - if(!istype(container) || !container.reagents.has_reagent(/datum/reagent/peridaxon)) - return 0 - if (!..()) - return 0 - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - - if(BP_IS_ROBOTIC(affected)) - return 0 - - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - - var/list/dead_organs = list() - for(var/obj/item/organ/internal/I in target.internal_organs) - if(I && !(I.status & ORGAN_CUT_AWAY) && I.status & ORGAN_DEAD && I.parent_organ == affected.organ_tag && !BP_IS_ROBOTIC(I)) - var/image/img = tweak_image(I) - dead_organs[I] = img - - var/obj/item/organ/surgery_organ = preselected_organ - - if(preselected_organ && !(preselected_organ in dead_organs)) - return SURGERY_FAILURE - - if(!preselected_organ) - surgery_organ = show_radial_menu(user, target, dead_organs, require_near = TRUE) - - preselected_organ = null - - if(!surgery_organ || (!ignore_tool && (user.get_active_hand().return_item() != tool))) - return 0 - if(target.op_stage.current_organ) - to_chat(user, SPAN("warning", "You can't do this right now.")) - return SURGERY_FAILURE - if(!surgery_organ.can_recover() && istype(surgery_organ, /obj/item/organ/internal/cerebrum/brain)) - to_chat(user, SPAN("warning", "The [surgery_organ.name] is destroyed and can't be saved.")) - return SURGERY_FAILURE - - target.op_stage.current_organ = surgery_organ - return 1 - -/datum/surgery_step/internal/treat_necrosis/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts applying medication to the affected tissue in [target]'s [target.op_stage.current_organ] with \the [tool]." , \ - "You start applying medication to the affected tissue in [target]'s [target.op_stage.current_organ] with \the [tool].") - - target.custom_pain("Something in your [target.op_stage.current_organ] is causing you a lot of pain!",50) - ..() - -/datum/surgery_step/internal/treat_necrosis/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/internal/affected = target.op_stage.current_organ - var/obj/item/reagent_containers/container = tool - - var/amount = container.amount_per_transfer_from_this - var/datum/reagents/temp_reagents = new(amount, GLOB.temp_reagents_holder) - container.reagents.trans_to_holder(temp_reagents, amount) - - var/rejuvenate = temp_reagents.has_reagent(/datum/reagent/peridaxon) - - var/trans = temp_reagents.trans_to_mob(target, temp_reagents.total_volume, CHEM_BLOOD) //technically it's contact, but the reagents are being applied to internal tissue - if (trans > 0) - if(rejuvenate) - if(affected.can_recover()) - affected.damage = 0 - affected.status &= ~ORGAN_DEAD - affected.owner.update_body(1) - else - affected.damage = affected.min_broken_damage - affected.death_time = 0 - affected.owner.update_body(1) - - user.visible_message(SPAN("notice", "[user] applies [trans] unit\s of the solution to affected tissue in [target]'s [affected.name]"), \ - SPAN("notice", "You apply [trans] unit\s of the solution to affected tissue in [target]'s [affected.name] with \the [tool].")) - qdel(temp_reagents) - -/datum/surgery_step/internal/treat_necrosis/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) - - if (!istype(tool, /obj/item/reagent_containers)) - return - - var/obj/item/reagent_containers/container = tool - - var/trans = container.reagents.trans_to_mob(target, container.amount_per_transfer_from_this, CHEM_BLOOD) - - user.visible_message(SPAN("warning", "[user]'s hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!") , \ - SPAN("warning", "Your hand slips, applying [trans] units of the solution to the wrong place in [target]'s [affected.name] with the [tool]!")) - - //no damage or anything, just wastes medicine From bda4fa6dedfe7efa3c68aeb3aac546dd2f8489b3 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:45:19 +0300 Subject: [PATCH 16/37] convert face surgery steps --- baystation12.dme | 1 + code/datums/surgery/steps/face.dm | 172 ++++++++++++++++++++++++++++++ code/modules/surgery/face.dm | 150 -------------------------- 3 files changed, 173 insertions(+), 150 deletions(-) create mode 100644 code/datums/surgery/steps/face.dm delete mode 100644 code/modules/surgery/face.dm diff --git a/baystation12.dme b/baystation12.dme index 1e4a895abd8..05953579ac4 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -455,6 +455,7 @@ #include "code\datums\surgery\surgery_item.dm" #include "code\datums\surgery\surgery_status.dm" #include "code\datums\surgery\surgery_step.dm" +#include "code\datums\surgery\steps\face.dm" #include "code\datums\trading\_trading_defines.dm" #include "code\datums\trading\ai.dm" #include "code\datums\trading\armor.dm" diff --git a/code/datums/surgery/steps/face.dm b/code/datums/surgery/steps/face.dm new file mode 100644 index 00000000000..25887989067 --- /dev/null +++ b/code/datums/surgery/steps/face.dm @@ -0,0 +1,172 @@ +/** + * Generic face surgry step, does nothing. + */ +/datum/surgery_step/face + priority = 2 + +/datum/surgery_step/face/check_zone(mob/living/carbon/human/target, target_zone) + return (..() && target_zone == BP_MOUTH) + +/datum/surgery_step/face/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && !BP_IS_ROBOTIC(parent_organ)) + +/** + * Facial tissue cutting step. + */ +/datum/surgery_step/generic/cut_face + duration = CUT_DURATION * 1.25 + + allowed_tools = list( + /obj/item/scalpel = 100, + /obj/item/material/knife = 75, + /obj/item/material/shard = 50 + ) + +/datum/surgery_step/generic/cut_face/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && target.surgery_status.face == 0) + +/datum/surgery_step/generic/cut_face/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts to cut open [target]'s face and neck with \the [tool].", + "You start to cut open [target]'s face and neck with \the [tool]." + ) + return ..() + +/datum/surgery_step/generic/cut_face/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has cut open [target]'s face and neck with \the [tool].", + "You have cut open [target]'s face and neck with \the [tool]." + ) + target.surgery_status.face = 1 + +/datum/surgery_step/generic/cut_face/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, slicing [target]'s throat wth \the [tool]!", + "Your hand slips, slicing [target]'s throat wth \the [tool]!" + ) + parent_organ.take_external_damage( + 40, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + target.losebreath += 10 + +/** + * Vaocal mending step. + */ +/datum/surgery_step/face/mend_vocal + duration = CLAMP_DURATION * 1.25 + + allowed_tools = list( + /obj/item/hemostat = 100, + /obj/item/stack/cable_coil = 75, + /obj/item/device/assembly/mousetrap = 10 + ) + +/datum/surgery_step/face/mend_vocal/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && target.surgery_status.face == 1) + +/datum/surgery_step/face/mend_vocal/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts mending [target]'s vocal cords with \the [tool].", + "You start mending [target]'s vocal cords with \the [tool]." + ) + return ..() + +/datum/surgery_step/face/mend_vocal/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] mends [target]'s vocal cords with \the [tool].", + "You mend [target]'s vocal cords with \the [tool]." + ) + target.surgery_status.face = 2 + +/datum/surgery_step/face/mend_vocal/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, clamping [target]'s trachea shut for a moment with \the [tool]!", + "Your hand slips, clamping [user]'s trachea shut for a moment with \the [tool]!" + ) + target.losebreath += 10 + +/** + * Facial reconstruction step. + */ +/datum/surgery_step/face/fix_face + duration = RETRACT_DURATION * 1.25 + + allowed_tools = list( + /obj/item/retractor = 100, + /obj/item/crowbar = 55, + /obj/item/material/kitchen/utensil/fork = 75 + ) + +/datum/surgery_step/face/fix_face/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && target.surgery_status.face == 2) + +/datum/surgery_step/face/fix_face/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts pulling the skin on [target]'s face back in place with \the [tool].", + "You start pulling the skin on [target]'s face back in place with \the [tool].") + return ..() + +/datum/surgery_step/face/fix_face/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] pulls the skin on [target]'s face back in place with \the [tool].", + "You pull the skin on [target]'s face back in place with \the [tool]." + ) + target.surgery_status.face = 3 + +/datum/surgery_step/face/fix_face/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, tearing skin on [target]'s face with \the [tool]!", + "Your hand slips, tearing skin on [target]'s face with \the [tool]!" + ) + parent_organ.take_external_damage( + 10, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + +/** + * Facial cauterization step. + */ +/datum/surgery_step/face/cauterize + duration = CAUTERIZE_DURATION * 1.25 + + allowed_tools = list( + /obj/item/cautery = 100, + /obj/item/clothing/mask/smokable/cigarette = 75, + /obj/item/flame/lighter = 50, + /obj/item/weldingtool = 25, + /obj/item/hothands = 20 + ) + +/datum/surgery_step/face/cauterize/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && target.surgery_status.face > 0) + +/datum/surgery_step/face/cauterize/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] is beginning to cauterize the incision on [target]'s face and neck with \the [tool].", + "You are beginning to cauterize the incision on [target]'s face and neck with \the [tool]." + ) + return ..() + +/datum/surgery_step/face/cauterize/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] cauterizes the incision on [target]'s face and neck with \the [tool].", + "You cauterize the incision on [target]'s face and neck with \the [tool]." + ) + if(target.surgery_status.face == 3) + var/obj/item/organ/external/head/H = parent_organ + H.status &= ~ORGAN_DISFIGURED + H.deformities = 0 + target.surgery_status.face = 0 + target.update_deformities() + +/datum/surgery_step/face/cauterize/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[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]!" + ) + parent_organ.take_external_damage(0, 4, used_weapon = tool) diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm deleted file mode 100644 index 75792c26fa3..00000000000 --- a/code/modules/surgery/face.dm +++ /dev/null @@ -1,150 +0,0 @@ -//Procedures in this file: Facial reconstruction surgery -////////////////////////////////////////////////////////////////// -// FACE SURGERY // -////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////// -// generic face surgery step datum -////////////////////////////////////////////////////////////////// -/datum/surgery_step/face - priority = 2 - can_infect = 0 - -/datum/surgery_step/face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (!affected || BP_IS_ROBOTIC(affected)) - return 0 - return target_zone == BP_MOUTH - -////////////////////////////////////////////////////////////////// -// facial tissue cutting surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/generic/cut_face - allowed_tools = list( - /obj/item/scalpel = 100, \ - /obj/item/material/knife = 75, \ - /obj/item/material/shard = 50, \ - ) - - duration = CUT_DURATION * 1.25 - -/datum/surgery_step/generic/cut_face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target_zone == BP_MOUTH && target.op_stage.face == 0 - -/datum/surgery_step/generic/cut_face/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts to cut open [target]'s face and neck with \the [tool].", \ - "You start to cut open [target]'s face and neck with \the [tool].") - ..() - -/datum/surgery_step/generic/cut_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] has cut open [target]'s face and neck with \the [tool]." , \ - "You have cut open [target]'s face and neck with \the [tool].",) - target.op_stage.face = 1 - -/datum/surgery_step/generic/cut_face/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, slicing [target]'s throat wth \the [tool]!" , \ - "Your hand slips, slicing [target]'s throat wth \the [tool]!" ) - affected.take_external_damage(40, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - target.losebreath += 10 - -////////////////////////////////////////////////////////////////// -// vocal cord mending surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/face/mend_vocal - allowed_tools = list( - /obj/item/hemostat = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/device/assembly/mousetrap = 10 //I don't know. Don't ask me. But I'm leaving it because hilarity. - ) - - duration = CLAMP_DURATION * 1.25 - -/datum/surgery_step/face/mend_vocal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.face == 1 - -/datum/surgery_step/face/mend_vocal/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts mending [target]'s vocal cords with \the [tool].", \ - "You start mending [target]'s vocal cords with \the [tool].") - ..() - -/datum/surgery_step/face/mend_vocal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] mends [target]'s vocal cords with \the [tool].", \ - "You mend [target]'s vocal cords with \the [tool].") - target.op_stage.face = 2 - -/datum/surgery_step/face/mend_vocal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user]'s hand slips, clamping [target]'s trachea shut for a moment with \the [tool]!", \ - "Your hand slips, clamping [user]'s trachea shut for a moment with \the [tool]!") - target.losebreath += 10 - -////////////////////////////////////////////////////////////////// -// facial reconstruction surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/face/fix_face - allowed_tools = list( - /obj/item/retractor = 100, \ - /obj/item/crowbar = 55, \ - /obj/item/material/kitchen/utensil/fork = 75) - - duration = RETRACT_DURATION * 1.25 - -/datum/surgery_step/face/fix_face/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.face == 2 - -/datum/surgery_step/face/fix_face/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts pulling the skin on [target]'s face back in place with \the [tool].", \ - "You start pulling the skin on [target]'s face back in place with \the [tool].") - ..() - -/datum/surgery_step/face/fix_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] pulls the skin on [target]'s face back in place with \the [tool].", \ - "You pull the skin on [target]'s face back in place with \the [tool].") - target.op_stage.face = 3 - -/datum/surgery_step/face/fix_face/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, tearing skin on [target]'s face with \the [tool]!", \ - "Your hand slips, tearing skin on [target]'s face with \the [tool]!") - affected.take_external_damage(10, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// facial skin cauterization surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/face/cauterize - allowed_tools = list( - /obj/item/cautery = 100, \ - /obj/item/clothing/mask/smokable/cigarette = 75, \ - /obj/item/flame/lighter = 50, \ - /obj/item/weldingtool = 25, - /obj/item/hothands = 20 - ) - - duration = CAUTERIZE_DURATION * 1.25 - -/datum/surgery_step/face/cauterize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return ..() && target.op_stage.face > 0 - -/datum/surgery_step/face/cauterize/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] is beginning to cauterize the incision on [target]'s face and neck with \the [tool]." , \ - "You are beginning to cauterize the incision on [target]'s face and neck with \the [tool].") - ..() - -/datum/surgery_step/face/cauterize/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] cauterizes the incision on [target]'s face and neck with \the [tool].", \ - "You cauterize the incision on [target]'s face and neck with \the [tool].") - if (target.op_stage.face == 3) - var/obj/item/organ/external/head/h = affected - h.status &= ~ORGAN_DISFIGURED - h.deformities = 0 - target.op_stage.face = 0 - target.update_deformities() - -/datum/surgery_step/face/cauterize/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, 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]!") - affected.take_external_damage(0, 4, used_weapon = tool) From 5162ba252b3cdb4bf91b0a11ada4dcfb23300995 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:49:45 +0300 Subject: [PATCH 17/37] convert misc surgery steps --- baystation12.dme | 1 + code/datums/surgery/steps/misc.dm | 238 ++++++++++++++++++++++++++++++ code/modules/surgery/other.dm | 221 --------------------------- 3 files changed, 239 insertions(+), 221 deletions(-) create mode 100644 code/datums/surgery/steps/misc.dm delete mode 100644 code/modules/surgery/other.dm diff --git a/baystation12.dme b/baystation12.dme index 05953579ac4..ec56da41598 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -456,6 +456,7 @@ #include "code\datums\surgery\surgery_status.dm" #include "code\datums\surgery\surgery_step.dm" #include "code\datums\surgery\steps\face.dm" +#include "code\datums\surgery\steps\misc.dm" #include "code\datums\trading\_trading_defines.dm" #include "code\datums\trading\ai.dm" #include "code\datums\trading\armor.dm" diff --git a/code/datums/surgery/steps/misc.dm b/code/datums/surgery/steps/misc.dm new file mode 100644 index 00000000000..e33306fe657 --- /dev/null +++ b/code/datums/surgery/steps/misc.dm @@ -0,0 +1,238 @@ +/** + * Cutting powersuit step. + */ +/datum/surgery_step/powersuit + priority = 3 + duration = SAW_DURATION * 2 + + allowed_tools = list( + /obj/item/weldingtool = 80, + /obj/item/circular_saw = 60, + /obj/item/gun/energy/plasmacutter = 30 + ) + +/datum/surgery_step/powersuit/check_zone(mob/living/carbon/human/target, target_zone) + return (..() && target_zone == BP_CHEST) + +/datum/surgery_step/powersuit/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(!istype(target.back, /obj/item/rig)) + return FALSE + + if(isWelder(tool)) + var/obj/item/weldingtool/W = tool + if(!W.isOn() || !W.remove_fuel(1, user)) + return FALSE + + return !(target.back.canremove) + +/datum/surgery_step/powersuit/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts cutting through the support systems of [target]'s [target.back] with \the [tool].", + "You start cutting through the support systems of [target]'s [target.back] with \the [tool]." + ) + return ..() + +/datum/surgery_step/powersuit/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/rig/R = target.back + if(!istype(R)) + return + + R.reset() + announce_success(user, + "[user] has cut through the support systems of [target]'s [R] with \the [tool].", + "You have cut through the support systems of [target]'s [R] with \the [tool]." + ) + +/datum/surgery_step/powersuit/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s [tool] can't quite seem to get through the metal...", + "Your [tool] can't quite seem to get through the metal. It's weakening, though - try again." + ) + +/** + * Limb sterialization step. + */ +/datum/surgery_step/sterilize + priority = 2 + duration = STERILIZATION_DURATION + + allowed_tools = list( + /obj/item/reagent_containers/spray = 100, + /obj/item/reagent_containers/dropper = 100, + /obj/item/reagent_containers/vessel/bottle/chemical = 90, + /obj/item/reagent_containers/vessel/flask = 90, + /obj/item/reagent_containers/vessel/beaker = 75, + /obj/item/reagent_containers/vessel/bottle = 75, + /obj/item/reagent_containers/vessel/glass = 75, + /obj/item/reagent_containers/vessel/bucket = 50 + ) + +/datum/surgery_step/sterilize/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(parent_organ.is_disinfected()) + return FALSE + + var/obj/item/reagent_containers/C = tool + if(!istype(C) || !C.is_open_container()) + return FALSE + + var/datum/reagent/ethanol/E = locate() in C.reagents.reagent_list + if(istype(E) && E.strength >= 40) + return FALSE + + if(!istype(E) && !C.reagents.has_reagent(/datum/reagent/sterilizine)) + return FALSE + + return TRUE + +/datum/surgery_step/sterilize/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts pouring [tool]'s contents on \the [target]'s [parent_organ]." , \ + "You start pouring [tool]'s contents on \the [target]'s [parent_organ]." + ) + target.custom_pain( + "Your [parent_organ] is on fire!", + 50, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/sterilize/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/reagent_containers/C = tool + var/transfered = C.reagents.trans_to_mob(target, C.amount_per_transfer_from_this, CHEM_BLOOD) + if(!transfered) + return + + announce_success(user, + "[user] rubs [target]'s [parent_organ] down with \the [tool]'s contents.", + "You rub [target]'s [parent_organ] down with \the [tool]'s contents." + ) + +/datum/surgery_step/sterilize/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/reagent_containers/C = tool + if(!istype(C)) + return + + var/transfered = C.reagents.trans_to_mob(target, C.amount_per_transfer_from_this, CHEM_BLOOD) + if(!transfered) + return + + announce_failure(user, + "[user]'s hand slips, spilling \the [tool]'s contents over the [target]'s [parent_organ]!", + "Your hand slips, spilling \the [tool]'s contents over the [target]'s [parent_organ]!" + ) + parent_organ.disinfect() + +/** + * Fix tendon step. + */ +/datum/surgery_step/fix_tendon + can_infect = TRUE + delicate = TRUE + blood_level = BLOODY_HANDS + shock_level = 40 + priority = 2 + duration = CONNECT_DURATION + allowed_tools = list( + /obj/item/FixOVein = 100, + /obj/item/stack/cable_coil = 75, + /obj/item/tape_roll = 50 + ) + +/datum/surgery_step/fix_tendon/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(parent_organ.open() < SURGERY_RETRACTED) + return FALSE + + return (parent_organ.status & ORGAN_TENDON_CUT) + +/datum/surgery_step/fix_tendon/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts reattaching the damaged [parent_organ.tendon_name] in [target]'s [parent_organ] with \the [tool].", + "You start reattaching the damaged [parent_organ.tendon_name] in [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain( + "The pain in your [parent_organ] is unbearable!", + 100, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/fix_tendon/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has reattached the [parent_organ.tendon_name] in [target]'s [parent_organ] with \the [tool].", + "You have reattached the [parent_organ.tendon_name] in [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.status &= ~ORGAN_TENDON_CUT + parent_organ.update_damages() + +/datum/surgery_step/fix_tendon/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, smearing [tool] in the incision in [target]'s [parent_organ]!", + "Your hand slips, smearing [tool] in the incision in [target]'s [parent_organ]!" + ) + parent_organ.take_external_damage(5, used_weapon = tool) + +/** + * Fix vein inside a limb step. + */ +/datum/surgery_step/fix_vein + can_infect = TRUE + delicate = TRUE + blood_level = BLOODY_HANDS + shock_level = 40 + priority = 3 + duration = CONNECT_DURATION + + allowed_tools = list( + /obj/item/FixOVein = 100, + /obj/item/stack/cable_coil = 75, + /obj/item/tape_roll = 50 + ) + +/datum/surgery_step/fix_vein/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(parent_organ.open() < SURGERY_RETRACTED) + return FALSE + + return (parent_organ.status & ORGAN_ARTERY_CUT) + +/datum/surgery_step/fix_vein/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts patching the damaged [parent_organ.artery_name] in [target]'s [parent_organ] with \the [tool].", + "You start patching the damaged [parent_organ.artery_name] in [target]'s [parent_organ] with \the [tool]." + ) + target.custom_pain( + "The pain in your [parent_organ] is unbearable!", + 100, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/fix_vein/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has patched the [parent_organ.artery_name] in [target]'s [parent_organ] with \the [tool].", + "You have patched the [parent_organ.artery_name] in [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.status &= ~ORGAN_ARTERY_CUT + parent_organ.update_damages() + +/datum/surgery_step/fix_vein/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, smearing [tool] in the incision in [target]'s [parent_organ]!", + "Your hand slips, smearing [tool] in the incision in [target]'s [parent_organ]!" + ) + parent_organ.take_external_damage(5, used_weapon = tool) diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm deleted file mode 100644 index 0a0b3ec7811..00000000000 --- a/code/modules/surgery/other.dm +++ /dev/null @@ -1,221 +0,0 @@ -//Procedures in this file: Internal wound patching, Implant removal. -////////////////////////////////////////////////////////////////// -// INTERNAL WOUND PATCHING // -////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////// -// Tendon fix surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/fix_tendon - priority = 2 - allowed_tools = list( - /obj/item/FixOVein = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/tape_roll = 50 - ) - can_infect = 1 - blood_level = 1 - - duration = CONNECT_DURATION - shock_level = 40 - delicate = 1 - -/datum/surgery_step/fix_tendon/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && (affected.status & ORGAN_TENDON_CUT) && affected.open() >= SURGERY_RETRACTED - -/datum/surgery_step/fix_tendon/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 reattaching the damaged [affected.tendon_name] in [target]'s [affected.name] with \the [tool]." , \ - "You start reattaching the damaged [affected.tendon_name] in [target]'s [affected.name] with \the [tool].") - target.custom_pain("The pain in your [affected.name] is unbearable!",100,affecting = affected) - ..() - -/datum/surgery_step/fix_tendon/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 reattached the [affected.tendon_name] in [target]'s [affected.name] with \the [tool].", \ - "You have reattached the [affected.tendon_name] in [target]'s [affected.name] with \the [tool].") - affected.status &= ~ORGAN_TENDON_CUT - affected.update_damages() - -/datum/surgery_step/fix_tendon/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, smearing [tool] in the incision in [target]'s [affected.name]!" , \ - "Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") - affected.take_external_damage(5, used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// IB fix surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/fix_vein - priority = 3 - allowed_tools = list( - /obj/item/FixOVein = 100, \ - /obj/item/stack/cable_coil = 75, \ - /obj/item/tape_roll = 50 - ) - can_infect = 1 - blood_level = 1 - - duration = CONNECT_DURATION - shock_level = 40 - delicate = 1 - -/datum/surgery_step/fix_vein/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && (affected.status & ORGAN_ARTERY_CUT) && affected.open() >= SURGERY_RETRACTED - -/datum/surgery_step/fix_vein/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 patching the damaged [affected.artery_name] in [target]'s [affected.name] with \the [tool]." , \ - "You start patching the damaged [affected.artery_name] in [target]'s [affected.name] with \the [tool].") - target.custom_pain("The pain in your [affected.name] is unbearable!",100,affecting = affected) - ..() - -/datum/surgery_step/fix_vein/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 patched the [affected.artery_name] in [target]'s [affected.name] with \the [tool].", \ - "You have patched the [affected.artery_name] in [target]'s [affected.name] with \the [tool].") - affected.status &= ~ORGAN_ARTERY_CUT - affected.update_damages() - -/datum/surgery_step/fix_vein/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, smearing [tool] in the incision in [target]'s [affected.name]!" , \ - "Your hand slips, smearing [tool] in the incision in [target]'s [affected.name]!") - affected.take_external_damage(5, used_weapon = tool) - - -////////////////////////////////////////////////////////////////// -// Powersuit removal surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/powersuit - allowed_tools = list( - /obj/item/weldingtool = 80, - /obj/item/circular_saw = 60, - /obj/item/gun/energy/plasmacutter = 30 - ) - - priority = 3 - can_infect = 0 - blood_level = 0 - - duration = SAW_DURATION * 2.0 - clothes_penalty = FALSE - -/datum/surgery_step/powersuit/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!istype(target)) - return 0 - if(isWelder(tool)) - var/obj/item/weldingtool/welder = tool - if(!welder.isOn() || !welder.remove_fuel(1,user)) - return 0 - return (target_zone == BP_CHEST) && istype(target.back, /obj/item/rig) && !(target.back.canremove) - -/datum/surgery_step/powersuit/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user] starts cutting through the support systems of [target]'s [target.back] with \the [tool]." , \ - "You start cutting through the support systems of [target]'s [target.back] with \the [tool].") - ..() - -/datum/surgery_step/powersuit/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - - var/obj/item/rig/rig = target.back - if(!istype(rig)) - return - rig.reset() - user.visible_message("[user] has cut through the support systems of [target]'s [rig] with \the [tool].", \ - "You have cut through the support systems of [target]'s [rig] with \the [tool].") - -/datum/surgery_step/powersuit/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - user.visible_message("[user]'s [tool] can't quite seem to get through the metal...", \ - "Your [tool] can't quite seem to get through the metal. It's weakening, though - try again.") - - -////////////////////////////////////////////////////////////////// -// Disinfection step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/sterilize - priority = 2 - allowed_tools = list( - /obj/item/reagent_containers/spray = 100, - /obj/item/reagent_containers/dropper = 100, - /obj/item/reagent_containers/vessel/bottle/chemical = 90, - /obj/item/reagent_containers/vessel/flask = 90, - /obj/item/reagent_containers/vessel/beaker = 75, - /obj/item/reagent_containers/vessel/bottle = 75, - /obj/item/reagent_containers/vessel/glass = 75, - /obj/item/reagent_containers/vessel/bucket = 50 - ) - - can_infect = 0 - blood_level = 0 - - duration = 55 - -/datum/surgery_step/sterilize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!istype(affected)) - return 0 - if(affected.is_disinfected()) - return 0 - var/obj/item/reagent_containers/container = tool - if(!istype(container)) - return 0 - if(!container.is_open_container()) - return 0 - var/datum/reagent/ethanol/booze = locate() in container.reagents.reagent_list - if(istype(booze) && booze.strength >= 40) - to_chat(user, "[booze] is too weak, you need something of higher proof for this...") - return 0 - if(!istype(booze) && !container.reagents.has_reagent(/datum/reagent/sterilizine)) - return 0 - return 1 - -/datum/surgery_step/sterilize/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 pouring [tool]'s contents on \the [target]'s [affected.name]." , \ - "You start pouring [tool]'s contents on \the [target]'s [affected.name].") - target.custom_pain("Your [affected.name] is on fire!",50,affecting = affected) - ..() - -/datum/surgery_step/sterilize/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 (!istype(tool, /obj/item/reagent_containers)) - return - - var/obj/item/reagent_containers/container = tool - - var/amount = container.amount_per_transfer_from_this - var/temp_holder = new /obj() - var/datum/reagents/temp_reagents = new(amount, temp_holder) - container.reagents.trans_to_holder(temp_reagents, amount) - - var/trans = temp_reagents.trans_to_mob(target, temp_reagents.total_volume, CHEM_BLOOD) //technically it's contact, but the reagents are being applied to internal tissue - if (trans > 0) - user.visible_message("[user] rubs [target]'s [affected.name] down with \the [tool]'s contents.", \ - "You rub [target]'s [affected.name] down with \the [tool]'s contents.") - qdel(temp_reagents) - qdel(temp_holder) - -/datum/surgery_step/sterilize/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) - - if (!istype(tool, /obj/item/reagent_containers)) - return - - var/obj/item/reagent_containers/container = tool - - container.reagents.trans_to_mob(target, container.amount_per_transfer_from_this, CHEM_BLOOD) - - user.visible_message("[user]'s hand slips, spilling \the [tool]'s contents over the [target]'s [affected.name]!" , \ - "Your hand slips, spilling \the [tool]'s contents over the [target]'s [affected.name]!") - affected.disinfect() - From 87fd190cef13041b53747b40c80d1218f857c196 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:50:07 +0300 Subject: [PATCH 18/37] purge metroid surgery steps --- code/modules/surgery/metroids.dm | 109 ------------------------------- 1 file changed, 109 deletions(-) delete mode 100644 code/modules/surgery/metroids.dm diff --git a/code/modules/surgery/metroids.dm b/code/modules/surgery/metroids.dm deleted file mode 100644 index 98e83922a91..00000000000 --- a/code/modules/surgery/metroids.dm +++ /dev/null @@ -1,109 +0,0 @@ -//Procedures in this file: Metroid surgery, core extraction. -////////////////////////////////////////////////////////////////// -// METROID CORE EXTRACTION // -////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////// -// generic metroid surgery step datum -////////////////////////////////////////////////////////////////// -/datum/surgery_step/metroid - -/datum/surgery_step/metroid/is_valid_target(mob/living/carbon/metroid/target) - return istype(target, /mob/living/carbon/metroid/) - -/datum/surgery_step/metroid/can_use(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - return target.stat == 2 - -////////////////////////////////////////////////////////////////// -// metroid flesh cutting surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/metroid/cut_flesh - allowed_tools = list( - /obj/item/scalpel = 100, \ - /obj/item/material/knife = 75, \ - /obj/item/material/shard = 50, \ - ) - - duration = CUT_DURATION - clothes_penalty = FALSE - -/datum/surgery_step/metroid/cut_flesh/can_use(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - return ..() && istype(target) && target.core_removal_stage == 0 - -/datum/surgery_step/metroid/cut_flesh/begin_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - user.visible_message("[user] starts cutting through [target]'s flesh with \the [tool].", \ - "You start cutting through [target]'s flesh with \the [tool].") - -/datum/surgery_step/metroid/cut_flesh/end_step(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - user.visible_message("[user] cuts through [target]'s flesh with \the [tool].", \ - "You cut through [target]'s flesh with \the [tool], revealing its silky innards.") - target.core_removal_stage = 1 - -/datum/surgery_step/metroid/cut_flesh/fail_step(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - user.visible_message("[user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \ - "Your hand slips, tearing [target]'s flesh with \the [tool]!") - -////////////////////////////////////////////////////////////////// -// metroid innards cutting surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/metroid/cut_innards - allowed_tools = list( - /obj/item/scalpel = 100, \ - /obj/item/material/knife = 75, \ - /obj/item/material/shard = 50, \ - ) - - duration = CUT_DURATION - clothes_penalty = FALSE - -/datum/surgery_step/metroid/cut_innards/can_use(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - return ..() && istype(target) && target.core_removal_stage == 1 - -/datum/surgery_step/metroid/cut_innards/begin_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \ - "You start cutting [target]'s silky innards apart with \the [tool].") - -/datum/surgery_step/metroid/cut_innards/end_step(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - user.visible_message("[user] cuts [target]'s innards apart with \the [tool], exposing the cores.", \ - "You cut [target]'s innards apart with \the [tool], exposing the cores.") - target.core_removal_stage = 2 - -/datum/surgery_step/metroid/cut_innards/fail_step(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - user.visible_message("[user]'s hand slips, tearing [target]'s innards with \the [tool]!", \ - "Your hand slips, tearing [target]'s innards with \the [tool]!") - -////////////////////////////////////////////////////////////////// -// metroid core removal surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/metroid/saw_core - allowed_tools = list( - /obj/item/scalpel/manager = 100, \ - /obj/item/circular_saw = 100, \ - /obj/item/material/hatchet = 75 - ) - - duration = SAW_DURATION - clothes_penalty = FALSE - -/datum/surgery_step/metroid/saw_core/can_use(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - return ..() && (istype(target) && target.core_removal_stage == 2 && target.cores > 0) //This is being passed a human as target, unsure why. - -/datum/surgery_step/metroid/saw_core/begin_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - user.visible_message("[user] starts cutting out one of [target]'s cores with \the [tool].", \ - "You start cutting out one of [target]'s cores with \the [tool].") - -/datum/surgery_step/metroid/saw_core/end_step(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - target.cores-- - user.visible_message("[user] cuts out one of [target]'s cores with \the [tool].",, \ - "You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.") - - if(target.cores >= 0) - var/coreType = target.GetCoreType() - new coreType(target.loc) - if(target.cores <= 0) - target.icon_state = "[target.colour] baby metroid dead-nocore" - - -/datum/surgery_step/metroid/saw_core/fail_step(mob/living/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool) - user.visible_message("[user]'s hand slips, causing \him to miss the core!", \ - "Your hand slips, causing you to miss the core!") From 17220b677f6a74634202846d1e04f077124c214e Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:50:50 +0300 Subject: [PATCH 19/37] purge remaining old surgery files --- code/modules/surgery/_defines.dm | 18 --- code/modules/surgery/surgery.dm | 189 ------------------------------- code/modules/surgery/~defines.dm | 16 --- 3 files changed, 223 deletions(-) delete mode 100644 code/modules/surgery/_defines.dm delete mode 100644 code/modules/surgery/surgery.dm delete mode 100644 code/modules/surgery/~defines.dm diff --git a/code/modules/surgery/_defines.dm b/code/modules/surgery/_defines.dm deleted file mode 100644 index 9a0f9eab3c8..00000000000 --- a/code/modules/surgery/_defines.dm +++ /dev/null @@ -1,18 +0,0 @@ -#define SURGERY_FAILURE -1 -#define SURGERY_BLOCKED -2 - -/* some defines for often used surgery steps */ - -#define SURGERY_DURATION_DELTA rand(9,11) / 10 // delta multiplier for all surgeries, from 0.9 to 1.1 - -#define CUT_DURATION 30 // making cuts / unscrewing or deattaching organs -#define CLAMP_DURATION 35 // hemostat usage -#define RETRACT_DURATION 25 // retracting -#define CAUTERIZE_DURATION 35 // cautery -#define GLUE_BONE_DURATION 35 // bone glue -#define BONE_MEND_DURATION 40 // bone menders -#define SAW_DURATION 50 // saw -#define DRILL_DURATION 70 // drilling -#define ATTACH_DURATION 50 // attaching externals / putting something in -#define ORGAN_FIX_DURATION 35 // organs fixing / welding -#define CONNECT_DURATION 50 // fix o vein usage diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm deleted file mode 100644 index dd1b889da5d..00000000000 --- a/code/modules/surgery/surgery.dm +++ /dev/null @@ -1,189 +0,0 @@ -/* SURGERY STEPS */ - -/datum/surgery_step - var/priority = 0 //steps with higher priority would be attempted first - - // type path referencing tools that can be used for this step, and how well are they suited for it - var/list/allowed_tools = null - // type paths referencing races that this step applies to. - var/list/allowed_species = null - var/list/disallowed_species = null - - // duration of the step - var/duration = 0 - - // 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. - var/blood_level = 0 - var/shock_level = 0 //what shock level will this step put patient on - var/delicate = 0 //if this step NEEDS stable optable or can be done on any valid surface with no penalty - var/clothes_penalty = TRUE // If the selected limb is wearing something - add a penalty. - -/datum/surgery_step/proc/do_surgery_process(mob/living/carbon/M, atom/movable/user, zone, obj/item/tool, step_is_valid) - var/status = TRUE - if(clothes_penalty && clothes_check(user, M, zone) == SURGERY_BLOCKED) - return TRUE - if(step_is_valid == SURGERY_FAILURE) // This is a failure that already has a message for failing. - return TRUE - M.op_stage.in_progress += zone - begin_step(user, M, zone, tool) //start on it - //We had proper tools! (or RNG smiled.) and user did not move or change hands. - if(prob(success_chance(user, M, tool, zone)) && do_mob(user, M, duration * SURGERY_DURATION_DELTA * tool.surgery_speed)) - end_step(user, M, zone, tool) //finish successfully - else if ((tool in user.contents) && user.Adjacent(M)) //or - fail_step(user, M, zone, tool) //malpractice - else // This failing silently was a pain. - to_chat(user, SPAN("warning", "You must remain close to your patient to conduct surgery.")) - status = FALSE - if (M) - M.op_stage.in_progress -= zone // Clear the in-progress flag. - if (ishuman(M)) - var/mob/living/carbon/human/H = M - H.update_surgery() - if(H.op_stage.current_organ) - H.op_stage.current_organ = null //Clearing current surgery target for the sake of internal surgery's consistency - return status - -//returns how well tool is suited for this step -/datum/surgery_step/proc/tool_quality(obj/item/tool) - for (var/T in allowed_tools) - if (istype(tool,T)) - return allowed_tools[T] - return 0 - -// Checks if this step applies to the user mob at all -/datum/surgery_step/proc/is_valid_target(mob/living/carbon/human/target) - if(!hasorgans(target)) - return 0 - - if(allowed_species) - for(var/species in allowed_species) - if(target.species.name == species) - return 1 - - if(disallowed_species) - for(var/species in disallowed_species) - if(target.species.name == species) - return 0 - - return 1 - - -// checks whether this step can be applied with the given user and target -/datum/surgery_step/proc/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return 0 - -// does stuff to begin the step, usually just printing messages. Moved germs transfering and bloodying here too -/datum/surgery_step/proc/begin_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 (can_infect && affected) - spread_germs_to_organ(affected, user) - if (ishuman(user) && prob(60)) - var/mob/living/carbon/human/H = user - if (blood_level) - H.bloody_hands(target,0) - if (blood_level > 1) - H.bloody_body(target,0) - if(shock_level) - target.shock_stage = max(target.shock_stage, shock_level) - return - -// does stuff to end the step, which is normally print a message + do whatever this step changes -/datum/surgery_step/proc/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return - -// stuff that happens when the step fails -/datum/surgery_step/proc/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - return null - -/datum/surgery_step/proc/success_chance(mob/living/user, mob/living/carbon/human/target, obj/item/tool, target_zone) - . = tool_quality(tool) - if(user == target) - . -= 10 - if(ishuman(user)) - var/mob/living/carbon/human/H = user - . -= round(H.shock_stage * 0.5) - if(H.eye_blurry) - . -= 20 - if(H.eye_blind) - . -= 60 - - if(delicate) - if(ishuman(user) && user?.slurring) - . -= 10 - if(!target.lying) - . -= 30 - var/turf/T = get_turf(target) - if(locate(/obj/machinery/optable, T)) - . -= 0 - else if(locate(/obj/structure/bed, T)) - . -= 5 - else if(locate(/obj/structure/table, T)) - . -= 10 - else if(locate(/obj/effect/rune/, T)) - . -= 10 - . = max(., 0) - -/proc/clothes_check(user, target, target_zone) - var/list/clothes = get_target_clothes(target, target_zone) - for(var/obj/item/clothing/C in clothes) - if(!(C.body_parts_covered & body_part_flags[target_zone])) - continue - to_chat(user, SPAN_DANGER("Clothing on [target]'s [organ_name_by_zone(target, target_zone)] blocks surgery!")) - return SURGERY_BLOCKED - -/proc/spread_germs_to_organ(obj/item/organ/external/E, mob/living/carbon/human/user) - if(!istype(user) || !istype(E)) return - - var/germ_level = user.germ_level - var/obj/item/clothing/gloves/G = user.gloves - if(istype(G) && !(G.clipped && prob(75))) - germ_level = G.germ_level - - E.germ_level = max(germ_level,E.germ_level) //as funny as scrubbing microbes out with clean gloves is - no. - -/obj/item/proc/do_surgery(mob/living/carbon/M, mob/living/user) - if(!istype(M)) - return FALSE - if (user.a_intent == I_HURT) //check for Hippocratic Oath - return FALSE - var/zone = user.zone_sel.selecting - if(zone in M.op_stage.in_progress) //Can't operate on someone repeatedly. - to_chat(user, SPAN("warning", "You can't operate on this area while surgery is already in progress.")) - return TRUE - 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)) - S.do_surgery_process(M, user, zone, src, step_is_valid) - return TRUE // don't want to do weapony things after surgery - return FALSE - -/proc/sort_surgeries() - var/gap = surgery_steps.len - var/swapped = 1 - while (gap > 1 || swapped) - swapped = 0 - if(gap > 1) - gap = round(gap / 1.247330950103979) - if(gap < 1) - gap = 1 - for(var/i = 1; gap + i <= surgery_steps.len; i++) - var/datum/surgery_step/l = surgery_steps[i] //Fucking hate - var/datum/surgery_step/r = surgery_steps[gap+i] //how lists work here - if(l.priority < r.priority) - surgery_steps.Swap(i, gap + i) - swapped = 1 - -/datum/surgery_status/ - var/eyes = 0 - var/face = 0 - var/head_reattach = 0 - var/current_organ = "organ" - var/list/in_progress = list() - -/datum/surgery_status/Destroy() - in_progress.Cut() - return ..() diff --git a/code/modules/surgery/~defines.dm b/code/modules/surgery/~defines.dm deleted file mode 100644 index 7b2840c5a8c..00000000000 --- a/code/modules/surgery/~defines.dm +++ /dev/null @@ -1,16 +0,0 @@ -#undef SURGERY_FAILURE -#undef SURGERY_BLOCKED - -#undef SURGERY_DURATION_DELTA - -#undef CUT_DURATION -#undef CLAMP_DURATION -#undef RETRACT_DURATION -#undef CAUTERIZE_DURATION -#undef GLUE_BONE_DURATION -#undef BONE_MEND_DURATION -#undef SAW_DURATION -#undef DRILL_DURATION -#undef ATTACH_DURATION -#undef ORGAN_FIX_DURATION -#undef CONNECT_DURATION From 8220c027ecdc12027fc534e80be21d609ed8d1ef Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:54:40 +0300 Subject: [PATCH 20/37] fix associative issues --- code/datums/surgery/surgery_status.dm | 5 +++-- code/datums/surgery/surgery_step.dm | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/code/datums/surgery/surgery_status.dm b/code/datums/surgery/surgery_status.dm index 95b648fd28c..b76f3683ebb 100644 --- a/code/datums/surgery/surgery_status.dm +++ b/code/datums/surgery/surgery_status.dm @@ -10,11 +10,12 @@ * Exists 'cause of integrated crcuits. */ var/list/operated_organs = list() + /// Number, used to detemine current face surgery step, refactor this shit. + var/face = 0 /datum/surgery_status/proc/start_surgery(obj/item/organ/target_organ, target_zone) LAZYADD(ongoing_steps, target_zone) LAZYADDASSOC(operated_organs, target_zone, target_organ) /datum/surgery_status/proc/stop_surgery(target_zone) - LAZYREMOVE(ongoing_steps, target_zone) - LAZYREMOVE(operated_organs, target_zone) + operated_organs[target_zone] = null diff --git a/code/datums/surgery/surgery_step.dm b/code/datums/surgery/surgery_step.dm index b3196bb9d60..3853b6b34cc 100644 --- a/code/datums/surgery/surgery_step.dm +++ b/code/datums/surgery/surgery_step.dm @@ -85,7 +85,7 @@ // At this point we can access selected organ via `surgery_status`. target.surgery_status.start_surgery(target_organ, parent_zone) initiate(parent_organ, target_organ, target, tool, user) - target.surgery_status.stop_surgery(target_organ, parent_zone) + target.surgery_status.stop_surgery(parent_zone) target.update_surgery() From 773b351954b4e21750cfedaea629c14d5a1e62ea Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:49:30 +0300 Subject: [PATCH 21/37] convert robotic surgery steps --- baystation12.dme | 1 + code/datums/surgery/steps/robotic.dm | 441 +++++++++++++++++++++++++++ code/modules/surgery/robotics.dm | 411 ------------------------- 3 files changed, 442 insertions(+), 411 deletions(-) create mode 100644 code/datums/surgery/steps/robotic.dm delete mode 100644 code/modules/surgery/robotics.dm diff --git a/baystation12.dme b/baystation12.dme index ec56da41598..e3ea707458b 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -457,6 +457,7 @@ #include "code\datums\surgery\surgery_step.dm" #include "code\datums\surgery\steps\face.dm" #include "code\datums\surgery\steps\misc.dm" +#include "code\datums\surgery\steps\robotic.dm" #include "code\datums\trading\_trading_defines.dm" #include "code\datums\trading\ai.dm" #include "code\datums\trading\armor.dm" diff --git a/code/datums/surgery/steps/robotic.dm b/code/datums/surgery/steps/robotic.dm new file mode 100644 index 00000000000..2caef89f3db --- /dev/null +++ b/code/datums/surgery/steps/robotic.dm @@ -0,0 +1,441 @@ +/** + * Generic robotic surgery step, does nothing. + */ +/datum/surgery_step/robotic/check_zone(mob/living/carbon/human/target, target_zone) + return (..() && target_zone != BP_MOUTH) + +/datum/surgery_step/robotic/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(parent_organ.status & ORGAN_CUT_AWAY) + return FALSE + + return BP_IS_ROBOTIC(parent_organ) + +////////////////////////////////////////////////////////////////// +// unscrew robotic limb hatch surgery step +////////////////////////////////////////////////////////////////// +/datum/surgery_step/robotic/unscrew_hatch + duration = CUT_DURATION + + allowed_tools = list( + /obj/item/screwdriver = 100, + /obj/item/material/coin = 50, + /obj/item/material/kitchen/utensil/knife = 50 + ) + +/datum/surgery_step/robotic/unscrew_hatch/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return ..() && parent_organ.hatch_state == HATCH_CLOSED + +/datum/surgery_step/robotic/unscrew_hatch/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts to unscrew the maintenance hatch on [target]'s [parent_organ] with \the [tool].", + "You start to unscrew the maintenance hatch on [target]'s [parent_organ] with \the [tool]." + ) + return ..() + +/datum/surgery_step/robotic/unscrew_hatch/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has opened the maintenance hatch on [target]'s [parent_organ] with \the [tool].", + "You have opened the maintenance hatch on [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.hatch_state = HATCH_UNSCREWED + +/datum/surgery_step/robotic/unscrew_hatch/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s [tool] slips, failing to unscrew [target]'s [parent_organ].", + "Your [tool] slips, failing to unscrew [target]'s [parent_organ]." + ) + +/** + * Hatch screwing step. + */ +/datum/surgery_step/robotic/screw_hatch + duration = CUT_DURATION + + allowed_tools = list( + /obj/item/screwdriver = 100, + /obj/item/material/coin = 50, + /obj/item/material/kitchen/utensil/knife = 50 + ) + +/datum/surgery_step/robotic/screw_hatch/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.hatch_state == HATCH_UNSCREWED) + +/datum/surgery_step/robotic/screw_hatch/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts to screw down the maintenance hatch on [target]'s [parent_organ] with \the [tool].", + "You start to screw down the maintenance hatch on [target]'s [parent_organ] with \the [tool]." + ) + return..() + +/datum/surgery_step/robotic/screw_hatch/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has screwed down the maintenance hatch on [target]'s [parent_organ] with \the [tool].", + "You have screwed down the maintenance hatch on [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.hatch_state = HATCH_CLOSED + +/datum/surgery_step/robotic/screw_hatch/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s [tool.name] slips, failing to screw down [target]'s [parent_organ].", + "Your [tool] slips, failing to screw down [target]'s [parent_organ]." + ) + +/** + * Open robotic limb step. + */ +/datum/surgery_step/robotic/open_hatch + duration = RETRACT_DURATION + + allowed_tools = list( + /obj/item/retractor = 100, + /obj/item/crowbar = 100, + /obj/item/material/kitchen/utensil = 50 + ) + +/datum/surgery_step/robotic/open_hatch/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.hatch_state == HATCH_UNSCREWED) + +/datum/surgery_step/robotic/open_hatch/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts to pry open the maintenance hatch on [target]'s [parent_organ] with \the [tool].", + "You start to pry open the maintenance hatch on [target]'s [parent_organ] with \the [tool]." + ) + return ..() + +/datum/surgery_step/robotic/open_hatch/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] opens the maintenance hatch on [target]'s [parent_organ] with \the [tool].", + "You open the maintenance hatch on [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.hatch_state = HATCH_OPENED + +/datum/surgery_step/robotic/open_hatch/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s [tool] slips, failing to open the hatch on [target]'s [parent_organ].", + "Your [tool] slips, failing to open the hatch on [target]'s [parent_organ]." + ) + +/** + * Close robotic limb step. + */ +/datum/surgery_step/robotic/close_hatch + allowed_tools = list( + /obj/item/retractor = 100, + /obj/item/crowbar = 100, + /obj/item/material/kitchen/utensil = 50 + ) + + duration = RETRACT_DURATION + +/datum/surgery_step/robotic/close_hatch/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.hatch_state == HATCH_OPENED) + +/datum/surgery_step/robotic/close_hatch/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] begins to close the hatch on [target]'s [parent_organ] with \the [tool].", + "You begin to close the hatch on [target]'s [parent_organ] with \the [tool]." + ) + return ..() + +/datum/surgery_step/robotic/close_hatch/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] closes the hatch on [target]'s [parent_organ] with \the [tool].", + "You close the hatch on [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.hatch_state = HATCH_UNSCREWED + parent_organ.germ_level = 0 + +/datum/surgery_step/robotic/close_hatch/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s [tool] slips, failing to close the hatch on [target]'s [parent_organ].", + "Your [tool] slips, failing to close the hatch on [target]'s [parent_organ]." + ) + +/** + * Robotic limb brute repair step. + */ +/datum/surgery_step/robotic/repair_brute + duration = ORGAN_FIX_DURATION + + allowed_tools = list( + /obj/item/weldingtool = 100, + /obj/item/gun/energy/plasmacutter = 50 + ) + +/datum/surgery_step/robotic/repair_brute/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(isWelder(tool)) + var/obj/item/weldingtool/W = tool + if(!W.isOn() || !W.remove_fuel(1, user)) + return FALSE + + if(parent_organ.hatch_state != HATCH_OPENED) + return FALSE + + return ((parent_organ.status & ORGAN_DISFIGURED) || parent_organ.brute_dam > 0) + +/datum/surgery_step/robotic/repair_brute/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] begins to patch damage to [target]'s [parent_organ]'s support structure with \the [tool].", + "You begin to patch damage to [target]'s [parent_organ]'s support structure with \the [tool]." + ) + return ..() + +/datum/surgery_step/robotic/repair_brute/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] finishes patching damage to [target]'s [parent_organ] with \the [tool].", + "You finish patching damage to [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.heal_damage(rand(30, 50), 0, 1, 1) + parent_organ.status &= ~ORGAN_DISFIGURED + +/datum/surgery_step/robotic/repair_brute/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s [tool] slips, damaging the internal structure of [target]'s [parent_organ].", + "Your [tool] slips, damaging the internal structure of [target]'s [parent_organ]." + ) + parent_organ.take_external_damage(0, rand(5, 10), 0, used_weapon = tool) + +/** + * Robotic limb burn damage repair step. + */ +/datum/surgery_step/robotic/repair_burn + duration = CONNECT_DURATION + + allowed_tools = list( + /obj/item/stack/cable_coil = 100 + ) + +/datum/surgery_step/robotic/repair_burn/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(parent_organ.hatch_state != HATCH_OPENED) + return FALSE + + if(parent_organ.burn_dam <= 0 && !(parent_organ.status & ORGAN_DISFIGURED)) + return FALSE + + var/obj/item/stack/cable_coil/C = tool + if(!istype(C)) + return + + if(!C.use(3)) + target.show_splash_text(user, "not enough coil length!") + return FALSE + + return TRUE + +/datum/surgery_step/robotic/repair_burn/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] begins to splice new cabling into [target]'s [parent_organ].", + "You begin to splice new cabling into [target]'s [parent_organ]." + ) + return ..() + +/datum/surgery_step/robotic/repair_burn/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] finishes splicing cable into [target]'s [parent_organ].", + "You finishes splicing new cable into [target]'s [parent_organ]." + ) + parent_organ.heal_damage(0, rand(30, 50), 1, 1) + parent_organ.status &= ~ORGAN_DISFIGURED + +/datum/surgery_step/robotic/repair_burn/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user] causes a short circuit in [target]'s [parent_organ]!", + "You cause a short circuit in [target]'s [parent_organ]!" + ) + target.apply_damage(rand(5, 10), BURN, parent_organ) + +/** + * Default robotic internal step, does nothing. + */ +/datum/surgery_step/robotics/internal/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.hatch_state == HATCH_OPENED) + +/datum/surgery_step/robotics/internal/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + return target.surgery_status.operated_organs[get_parent_zone(target_zone)] + +/** + * Robotic organ detachment step. + */ +/datum/surgery_step/robotics/internal/detatch_organ + duration = CUT_DURATION * 1.75 + + allowed_tools = list( + /obj/item/device/multitool = 100 + ) + +/datum/surgery_step/robotics/internal/detatch_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + var/list/attached_organs = list() + for(var/obj/item/organ/O in target.internal_organs) + if(O.parent_organ != target_zone) + continue + + if(!(O.status & ORGAN_CUT_AWAY)) + attached_organs[O] = agjust_organ_image(O) + + var/obj/item/organ/preselected_organ = ..() + if(istype(preselected_organ)) + if(preselected_organ in attached_organs) + return preselected_organ + + return null + + var/obj/item/organ/selected_organ = show_radial_menu(user, target, attached_organs, require_near = TRUE) + if(!istype(selected_organ)) + return null + + return selected_organ + +/datum/surgery_step/robotics/internal/detatch_organ/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts to decouple [target]'s [target_organ] with \the [tool].", + "You start to decouple [target]'s [target_organ] with \the [tool]." + ) + return ..() + +/datum/surgery_step/robotics/internal/detatch_organ/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/obj/item/organ/internal/I = target_organ + if(!istype(I)) + return + + announce_success(user, + "[user] has decoupled [target]'s [I] with \the [tool].", + "You have decoupled [target]'s [I] with \the [tool]." + ) + I.cut_away(user) + +/datum/surgery_step/robotics/internal/detatch_organ/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, disconnecting \the [tool].", + "Your hand slips, disconnecting \the [tool]." + ) + +////////////////////////////////////////////////////////////////// +// robotic organ transplant finalization surgery step +////////////////////////////////////////////////////////////////// +/datum/surgery_step/robotics/internal/attach_organ + allowed_tools = list( + /obj/item/screwdriver = 100 + ) + + duration = CONNECT_DURATION + +/datum/surgery_step/robotics/internal/attach_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + var/list/attachable_organs = list() + var/obj/item/organ/external/parent_organ = target.get_organ(target_zone) + for(var/obj/item/organ/O in parent_organ.implants) + if(O.parent_organ != target_zone) + continue + + if(O.status & ORGAN_CUT_AWAY) + attachable_organs[O] = agjust_organ_image(O) + + var/obj/item/organ/preselected_organ = ..() + if(istype(preselected_organ)) + if(preselected_organ in attachable_organs) + return preselected_organ + + return null + + var/obj/item/organ/selected_organ = show_radial_menu(user, target, attachable_organs, require_near = TRUE) + if(!istype(selected_organ)) + return null + + return selected_organ + +/datum/surgery_step/robotics/internal/attach_organ/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] begins reattaching [target]'s [target_organ] with \the [tool].", + "You start reattaching [target]'s [target_organ] with \the [tool]." + ) + return ..() + +/datum/surgery_step/robotics/internal/attach_organ/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] has reattached [target]'s [target_organ] with \the [tool].", + "You have reattached [target]'s [target_organ] with \the [tool]." + ) + target_organ.status &= ~ORGAN_CUT_AWAY + parent_organ.implants -= target_organ + target_organ.replaced(target, parent_organ) + +/datum/surgery_step/robotics/internal/attach_organ/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, disconnecting \the [tool].", + "Your hand slips, disconnecting \the [tool]." + ) + +/** + * Artificial organ repair step. + */ +/datum/surgery_step/robotic/fix_organ + duration = ORGAN_FIX_DURATION + + allowed_tools = list( + /obj/item/stack/nanopaste = 100, + /obj/item/bonegel = 30, + /obj/item/screwdriver = 70 + ) + +/datum/surgery_step/robotic/fix_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + if(!istype(parent_organ)) + return FALSE + + for(var/obj/item/organ/internal/I in parent_organ.internal_organs) + if(!BP_IS_ROBOTIC(I) || I.damage <= 0) + continue + + if(I.surface_accessible) + return TRUE + + if(parent_organ.open() >= (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED) || parent_organ.hatch_state == HATCH_OPENED) + return TRUE + + return FALSE + +/datum/surgery_step/robotic/fix_organ/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return TRUE + +/datum/surgery_step/robotic/fix_organ/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts mending the damage to mechanisms inside [target]'s [parent_organ].", + "You start mending the damage to mechanisms inside [target]'s [parent_organ]." + ) + return ..() + +/datum/surgery_step/robotic/fix_organ/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + for(var/obj/item/organ/I in parent_organ.internal_organs) + if(I.damage <= 0) + continue + + if(!BP_IS_ROBOTIC(I)) + continue + + announce_success(user, + "[user] repairs [target]'s [I] with \the [tool].", + "You repair [target]'s [I] with \the [tool]." + ) + I.damage = 0 + +/datum/surgery_step/robotic/fix_organ/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, gumming up the mechanisms inside of [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, gumming up the mechanisms inside of [target]'s [parent_organ] with \the [tool]!" + ) + + target.adjustToxLoss(5) + parent_organ.createwound(CUT, 5) + + for(var/obj/item/organ/internal/I in parent_organ.internal_organs) + I.take_internal_damage(rand(3, 5), 0) diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm deleted file mode 100644 index 9f069d6dd5f..00000000000 --- a/code/modules/surgery/robotics.dm +++ /dev/null @@ -1,411 +0,0 @@ -//Procedures in this file: Robotic surgery steps, organ removal, replacement. MMI insertion, synthetic organ repair. -////////////////////////////////////////////////////////////////// -// ROBOTIC SURGERY // -////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////// -// generic robotic surgery step datum -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/ - can_infect = 0 -/datum/surgery_step/robotics/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if (!istype(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if (affected == null) - return 0 - if (affected.status & ORGAN_CUT_AWAY) - return 0 - if (!BP_IS_ROBOTIC(affected)) - return 0 - return 1 - -////////////////////////////////////////////////////////////////// -// unscrew robotic limb hatch surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/unscrew_hatch - allowed_tools = list( - /obj/item/screwdriver = 100, - /obj/item/material/coin = 50, - /obj/item/material/kitchen/utensil/knife = 50 - ) - - duration = CUT_DURATION - -/datum/surgery_step/robotics/unscrew_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.hatch_state == HATCH_CLOSED && target_zone != BP_MOUTH - -/datum/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].", \ - "You start to unscrew the maintenance hatch on [target]'s [affected.name] with \the [tool].") - ..() - -/datum/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].", \ - "You have opened the maintenance hatch on [target]'s [affected.name] with \the [tool].",) - affected.hatch_state = HATCH_UNSCREWED - -/datum/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("[user]'s [tool.name] slips, failing to unscrew [target]'s [affected.name].", \ - "Your [tool] slips, failing to unscrew [target]'s [affected.name].") - -////////////////////////////////////////////////////////////////// -// screw robotic limb hatch surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/screw_hatch - allowed_tools = list( - /obj/item/screwdriver = 100, - /obj/item/material/coin = 50, - /obj/item/material/kitchen/utensil/knife = 50 - ) - - duration = CUT_DURATION - -/datum/surgery_step/robotics/screw_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.hatch_state == HATCH_UNSCREWED && target_zone != BP_MOUTH - -/datum/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 down the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ - "You start to screw down the maintenance hatch on [target]'s [affected.name] with \the [tool].") - ..() - -/datum/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 screwed down the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ - "You have screwed down the maintenance hatch on [target]'s [affected.name] with \the [tool].",) - affected.hatch_state = HATCH_CLOSED - -/datum/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("[user]'s [tool.name] slips, failing to screw down [target]'s [affected.name].", \ - "Your [tool] slips, failing to screw down [target]'s [affected.name].") - -////////////////////////////////////////////////////////////////// -// open robotic limb surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/open_hatch - allowed_tools = list( - /obj/item/retractor = 100, - /obj/item/crowbar = 100, - /obj/item/material/kitchen/utensil = 50 - ) - - duration = RETRACT_DURATION - -/datum/surgery_step/robotics/open_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.hatch_state == HATCH_UNSCREWED - -/datum/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].", - "You start to pry open the maintenance hatch on [target]'s [affected.name] with \the [tool].") - ..() - -/datum/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("[user] opens the maintenance hatch on [target]'s [affected.name] with \the [tool].", \ - "You open the maintenance hatch on [target]'s [affected.name] with \the [tool].") - affected.hatch_state = HATCH_OPENED - -/datum/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("[user]'s [tool.name] slips, failing to open the hatch on [target]'s [affected.name].", - "Your [tool] slips, failing to open the hatch on [target]'s [affected.name].") - -////////////////////////////////////////////////////////////////// -// close robotic limb surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/close_hatch - allowed_tools = list( - /obj/item/retractor = 100, - /obj/item/crowbar = 100, - /obj/item/material/kitchen/utensil = 50 - ) - - duration = RETRACT_DURATION - -/datum/surgery_step/robotics/close_hatch/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.hatch_state == HATCH_OPENED && target_zone != BP_MOUTH - -/datum/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]." , \ - "You begin to close the hatch on [target]'s [affected.name] with \the [tool].") - ..() - -/datum/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].", \ - "You close the hatch on [target]'s [affected.name] with \the [tool].") - affected.hatch_state = HATCH_UNSCREWED - affected.germ_level = 0 - -/datum/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("[user]'s [tool.name] slips, failing to close the hatch on [target]'s [affected.name].", - "Your [tool.name] slips, failing to close the hatch on [target]'s [affected.name].") - -////////////////////////////////////////////////////////////////// -// robotic limb brute damage repair surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/repair_brute - allowed_tools = list( - /obj/item/weldingtool = 100, - /obj/item/gun/energy/plasmacutter = 50 - ) - - duration = ORGAN_FIX_DURATION - -/datum/surgery_step/robotics/repair_brute/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(isWelder(tool)) - var/obj/item/weldingtool/welder = tool - if(!welder.isOn() || !welder.remove_fuel(1,user)) - return 0 - return affected && affected.hatch_state == HATCH_OPENED && ((affected.status & ORGAN_DISFIGURED) || affected.brute_dam > 0) && target_zone != BP_MOUTH - -/datum/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]." , \ - "You begin to patch damage to [target]'s [affected.name]'s support structure with \the [tool].") - ..() - -/datum/surgery_step/robotics/repair_brute/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 patching damage to [target]'s [affected.name] with \the [tool].", \ - "You finish patching damage to [target]'s [affected.name] with \the [tool].") - affected.heal_damage(rand(30,50),0,1,1) - affected.status &= ~ORGAN_DISFIGURED - -/datum/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("[user]'s [tool.name] slips, damaging the internal structure of [target]'s [affected.name].", - "Your [tool.name] slips, damaging the internal structure of [target]'s [affected.name].") - affected.take_external_damage(0, rand(5,10), 0, used_weapon = tool) - //target.apply_damage(rand(5,10), BURN, affected) - -////////////////////////////////////////////////////////////////// -// robotic limb burn damage repair surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/repair_burn - allowed_tools = list( - /obj/item/stack/cable_coil = 100 - ) - - duration = CONNECT_DURATION - -/datum/surgery_step/robotics/repair_burn/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - 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.hatch_state == HATCH_OPENED) && ((affected.status & ORGAN_DISFIGURED) || affected.burn_dam > 0) && target_zone != BP_MOUTH) - if(limb_can_operate) - if(istype(C)) - if(!C.get_amount() >= 3) - to_chat(user, "You need three or more cable pieces to repair this damage.") - return SURGERY_FAILURE - C.use(3) - return 1 - return SURGERY_FAILURE - -/datum/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]." , \ - "You begin to splice new cabling into [target]'s [affected.name].") - ..() - -/datum/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].", \ - "You finishes splicing new cable into [target]'s [affected.name].") - affected.heal_damage(0,rand(30,50),1,1) - affected.status &= ~ORGAN_DISFIGURED - -/datum/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("[user] causes a short circuit in [target]'s [affected.name]!", - "You cause a short circuit in [target]'s [affected.name]!") - target.apply_damage(rand(5,10), BURN, affected) - -////////////////////////////////////////////////////////////////// -// artificial organ repair surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/fix_organ_robotic //For artificial organs - allowed_tools = list( - /obj/item/stack/nanopaste = 100, \ - /obj/item/bonegel = 30, \ - /obj/item/screwdriver = 70, \ - ) - - duration = ORGAN_FIX_DURATION - -/datum/surgery_step/robotics/fix_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 - - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(BP_IS_ROBOTIC(I) && I.damage > 0) - if(I.surface_accessible) - return TRUE - if(affected.open() >= (affected.encased ? SURGERY_ENCASED : SURGERY_RETRACTED) || affected.hatch_state == HATCH_OPENED) - return TRUE - -/datum/surgery_step/robotics/fix_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(BP_IS_ROBOTIC(I)) - 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." ) - ..() - -/datum/surgery_step/robotics/fix_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(BP_IS_ROBOTIC(I)) - user.visible_message("[user] repairs [target]'s [I.name] with [tool].", \ - "You repair [target]'s [I.name] with [tool]." ) - I.damage = 0 - -/datum/surgery_step/robotics/fix_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.adjustToxLoss(5) - affected.createwound(CUT, 5) - - for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I) - I.take_internal_damage(rand(3,5), 0) - -////////////////////////////////////////////////////////////////// -// robotic organ detachment surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/detatch_organ_robotic - - allowed_tools = list( - /obj/item/device/multitool = 100 - ) - - duration = CUT_DURATION * 1.75 - -/datum/surgery_step/robotics/detatch_organ_robotic/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - - if(!..()) - return 0 - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(affected.hatch_state != HATCH_OPENED) - return 0 - - 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 = input(user, "Which organ do you want to prepare for removal?") as null|anything in attached_organs - if(!organ_to_remove) - return 0 - - target.op_stage.current_organ = organ_to_remove - - return 1 - -/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]." ) - ..() - -/datum/surgery_step/robotics/detatch_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]." , \ - "You have decoupled [target]'s [target.op_stage.current_organ] with \the [tool].") - - var/obj/item/organ/internal/I = target.internal_organs_by_name[target.op_stage.current_organ] - if(I && istype(I)) - I.cut_away(user) - -/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].", \ - "Your hand slips, disconnecting \the [tool].") - -////////////////////////////////////////////////////////////////// -// robotic organ transplant finalization surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/robotics/attach_organ_robotic - allowed_tools = list( - /obj/item/screwdriver = 100, - ) - - duration = CONNECT_DURATION - -/datum/surgery_step/robotics/attach_organ_robotic/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!(affected && (BP_IS_ROBOTIC(affected)))) - return 0 - if(affected.hatch_state != HATCH_OPENED) - return 0 - - target.op_stage.current_organ = null - - var/list/removable_organs = list() - for(var/obj/item/organ/I in affected.implants) - if ((I.status & ORGAN_CUT_AWAY) && (BP_IS_ROBOTIC(I)) && (I.parent_organ == target_zone)) - removable_organs |= I.organ_tag - - var/organ_to_replace = input(user, "Which organ do you want to reattach?") as null|anything in removable_organs - if(!organ_to_replace) - 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) - 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].") - ..() - -/datum/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]." , \ - "You have reattached [target]'s [target.op_stage.current_organ] with \the [tool].") - - var/obj/item/organ/external/affected = target.get_organ(target_zone) - for (var/obj/item/organ/I in affected.implants) - if (I.organ_tag == target.op_stage.current_organ) - I.status &= ~ORGAN_CUT_AWAY - affected.implants -= I - I.replaced(target, affected) - break - -/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].", \ - "Your hand slips, disconnecting \the [tool].") From 4b90fb1e47b738b0af5e5e4040cd22e73adc1c4b Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:50:12 +0300 Subject: [PATCH 22/37] fix checks and proc calls in internal steps --- code/datums/surgery/steps/internal.dm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/datums/surgery/steps/internal.dm b/code/datums/surgery/steps/internal.dm index 4a7da9e0fb4..1f7f2f130cb 100644 --- a/code/datums/surgery/steps/internal.dm +++ b/code/datums/surgery/steps/internal.dm @@ -36,7 +36,10 @@ var/list/attachable_organs = list() var/obj/item/organ/external/parent_organ = target.get_organ(target_zone) for(var/obj/item/organ/O in parent_organ.implants) - if(O && (O.status & ORGAN_CUT_AWAY)) + if(O.parent_organ != target_zone) + continue + + if(O.status & ORGAN_CUT_AWAY) attachable_organs[O] = agjust_organ_image(O) var/obj/item/organ/preselected_organ = ..() @@ -707,7 +710,7 @@ return TRUE /datum/surgery_step/internal/treat_necrosis/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) - user.visible_message( + announce_preop(user, "[user] starts applying medication to the affected tissue in [target]'s [parent_organ] with \the [tool].", "You start applying medication to the affected tissue in [target]'s [parent_organ] with \the [tool]." ) From 25676b5c350d1e62ccb1de09773df407031b97af Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:50:38 +0300 Subject: [PATCH 23/37] convert implant surgery steps --- baystation12.dme | 1 + code/datums/surgery/steps/implant.dm | 262 +++++++++++++++++++++++++++ code/modules/surgery/implant.dm | 242 ------------------------- 3 files changed, 263 insertions(+), 242 deletions(-) create mode 100644 code/datums/surgery/steps/implant.dm delete mode 100644 code/modules/surgery/implant.dm diff --git a/baystation12.dme b/baystation12.dme index e3ea707458b..58dc3f86259 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -456,6 +456,7 @@ #include "code\datums\surgery\surgery_status.dm" #include "code\datums\surgery\surgery_step.dm" #include "code\datums\surgery\steps\face.dm" +#include "code\datums\surgery\steps\implant.dm" #include "code\datums\surgery\steps\misc.dm" #include "code\datums\surgery\steps\robotic.dm" #include "code\datums\trading\_trading_defines.dm" diff --git a/code/datums/surgery/steps/implant.dm b/code/datums/surgery/steps/implant.dm new file mode 100644 index 00000000000..2df5cadb0da --- /dev/null +++ b/code/datums/surgery/steps/implant.dm @@ -0,0 +1,262 @@ +/** + * Generic implant step, does nothing. + */ +/datum/surgery_step/cavity + delicate = TRUE + shock_level = 40 + priority = 1 + +/datum/surgery_step/cavity/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(BP_IS_ROBOTIC(parent_organ)) + return parent_organ.hatch_state == HATCH_OPENED + + return parent_organ.open() >= (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED) + +/datum/surgery_step/cavity/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, scraping around inside [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, scraping around inside [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage( + 20, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + +/** + * Create cavity step. + */ +/datum/surgery_step/cavity/make_space + duration = DRILL_DURATION + + allowed_tools = list( + /obj/item/surgicaldrill = 100, + /obj/item/pen = 75, + /obj/item/stack/rods = 50 + ) + +/datum/surgery_step/cavity/make_space/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && !parent_organ.cavity) + +/datum/surgery_step/cavity/make_space/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts making some space inside [target]'s [parent_organ.cavity_name] cavity with \the [tool].", + "You start making some space inside [target]'s [parent_organ.cavity_name] cavity with \the [tool]." + ) + target.custom_pain( + "The pain in your chest is living hell!", + 1, + affecting = target_organ + ) + parent_organ.cavity = TRUE + return ..() + +/datum/surgery_step/cavity/make_space/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] makes some space inside [target]'s [parent_organ.cavity_name] cavity with \the [tool].", + "You make some space inside [target]'s [parent_organ.cavity_name] cavity with \the [tool]." + ) + +/** + * Cavity sealing step. + */ +/datum/surgery_step/cavity/close_space + priority = 2 + duration = CAUTERIZE_DURATION + + allowed_tools = list( + /obj/item/cautery = 100, + /obj/item/clothing/mask/smokable/cigarette = 75, + /obj/item/flame/lighter = 50, + /obj/item/weldingtool = 25 + ) + +/datum/surgery_step/cavity/close_space/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && parent_organ.cavity) + +/datum/surgery_step/cavity/close_space/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts mending [target]'s [parent_organ.cavity_name] cavity wall with \the [tool].", + "You start mending [target]'s [parent_organ.cavity_name] cavity wall with \the [tool]." + ) + target.custom_pain( + "The pain in your chest is living hell!", + 1, + affecting = parent_organ + ) + parent_organ.cavity = FALSE + return ..() + +/datum/surgery_step/cavity/close_space/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] mends [target]'s [parent_organ.cavity_name] cavity walls with \the [tool].", + "You mend [target]'s [parent_organ.cavity_name] cavity walls with \the [tool]." + ) + +/** + * Implanting surgery step. + */ +/datum/surgery_step/cavity/place_item + duration = ATTACH_DURATION + + allowed_tools = list( + /obj/item = 100 + ) + +/datum/surgery_step/cavity/place_item/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(issilicon(user)) + return FALSE + + if(!parent_organ.cavity) + return FALSE + + var/max_volume = base_storage_capacity(parent_organ.cavity_max_w_class) + parent_organ.internal_organs_size + for(var/obj/item/organ/internal/O in parent_organ.internal_organs) + max_volume -= O.get_storage_cost() + + if(tool.get_storage_cost() > max_volume || parent_organ.cavity_max_w_class < tool.w_class) + target.show_splash_text(user, "tool is too big!") + return FALSE + + var/total_volume = tool.get_storage_cost() + for(var/obj/item/I in parent_organ.implants) + if(istype(I, /obj/item/implant)) + continue + + total_volume += I.get_storage_cost() + + if(total_volume > max_volume) + target.show_splash_text(user, "not enough space!") + return FALSE + + return TRUE + +/datum/surgery_step/cavity/place_item/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts putting \the [tool] inside [target]'s [parent_organ.cavity_name] cavity.", + "You start putting \the [tool] inside [target]'s [parent_organ.cavity_name] cavity." + ) + target.custom_pain( + "The pain in your chest is living hell!", + 1, + affecting = parent_organ + ) + playsound(target.loc, 'sound/effects/squelch1.ogg', 25, 1) + return ..() + +/datum/surgery_step/cavity/place_item/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + if(!user.drop(tool, parent_organ)) + return + + announce_success(user, + "[user] puts \the [tool] inside [target]'s [parent_organ.cavity_name] cavity.", + "You put \the [tool] inside [target]'s [parent_organ.cavity_name] cavity." + ) + if(tool.w_class > parent_organ.cavity_max_w_class / 2 && prob(50) && !BP_IS_ROBOTIC(parent_organ) && parent_organ.sever_artery()) + to_chat(user, SPAN("warning", "You tear some blood vessels trying to fit such a big object in this cavity.")) + target.custom_pain( + "You feel something rip in your [parent_organ]!", + 1, + affecting = parent_organ + ) + parent_organ.implants += tool + parent_organ.cavity = FALSE + +/** + * Implant removal step. + */ +/datum/surgery_step/cavity/implant_removal + duration = CLAMP_DURATION + + allowed_tools = list( + /obj/item/hemostat = 100, + /obj/item/wirecutters = 75, + /obj/item/material/kitchen/utensil/fork = 20 + ) + +/datum/surgery_step/cavity/implant_removal/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] starts poking around inside [target]'s [parent_organ] with \the [tool].", + "You start poking around inside [target]'s [parent_organ] with \the [tool]" + ) + target.custom_pain( + "The pain in your [parent_organ] is living hell!", + 1, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/cavity/implant_removal/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + var/exposed = FALSE + if(BP_IS_ROBOTIC(parent_organ) && parent_organ.hatch_state == HATCH_OPENED) + exposed = TRUE + else if(parent_organ.open() >= (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED)) + exposed = TRUE + + var/find_prob = 0 + var/list/atom/loot = list() + if(exposed) + loot = parent_organ.implants + else + for(var/datum/wound/W in parent_organ.wounds) + loot |= W.embedded_objects + find_prob += 50 + + if(!length(loot)) + announce_success(user, + "[user] could not find anything inside [target]'s [parent_organ], and pulls \the [tool] out.", + "You could not find anything inside [target]'s [parent_organ]." + ) + return + + var/obj/item/implanted_item = pick(loot) + if(istype(implanted_item, /obj/item/implant)) + var/obj/item/implant/I = implanted_item + find_prob += I.islegal() ? 60 : 40 + else + find_prob += 50 + + if(prob(find_prob)) + announce_success(user, + "[user] takes something out of incision on [target]'s [parent_organ] with \the [tool].", + "You take [implanted_item] out of incision on [target]'s [parent_organ]s with \the [tool]." + ) + parent_organ.implants -= implanted_item + for(var/datum/wound/wound in parent_organ.wounds) + if(implanted_item in wound.embedded_objects) + wound.embedded_objects -= implanted_item + break + + playsound(target.loc, 'sound/effects/squelch1.ogg', 15, 1) + BITSET(target.hud_updateflag, IMPLOYAL_HUD) + + implanted_item.dropInto(target.loc) + implanted_item.add_blood(target) + implanted_item.update_icon() + if(istype(implanted_item, /obj/item/implant)) + var/obj/item/implant/I = implanted_item + I.removed() + return + + announce_success(user, + "[user] removes \the [tool] from [target]'s [parent_organ].", + "There's something inside [target]'s [parent_organ], but you just missed it this time." + ) + +/datum/surgery_step/cavity/implant_removal/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + . = ..() + for(var/obj/item/implant/I in parent_organ.implants) + if(prob(10 + 100 - get_tool_quality(tool))) + user.visible_message("Something beeps inside [target]'s [parent_organ]!") + playsound(I.loc, 'sound/items/countdown.ogg', 75, 1, -3) + spawn(25) + I.activate() diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm deleted file mode 100644 index b88421c8750..00000000000 --- a/code/modules/surgery/implant.dm +++ /dev/null @@ -1,242 +0,0 @@ -//Procedures in this file: Putting items in body cavity. Implant removal. Items removal. - -////////////////////////////////////////////////////////////////// -// ITEM PLACEMENT SURGERY // -////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////// -// generic implant surgery step datum -////////////////////////////////////////////////////////////////// -/datum/surgery_step/cavity - priority = 1 - shock_level = 40 - delicate = 1 -/datum/surgery_step/cavity/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(!hasorgans(target)) - return 0 - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) - return FALSE - if(BP_IS_ROBOTIC(affected)) - return affected.hatch_state == HATCH_OPENED - else - return affected.open() >= (affected.encased ? SURGERY_ENCASED : SURGERY_RETRACTED) - -/datum/surgery_step/cavity/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("[user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!", \ - "Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!") - affected.take_external_damage(20, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - -////////////////////////////////////////////////////////////////// -// create implant space surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/cavity/make_space - allowed_tools = list( - /obj/item/surgicaldrill = 100, \ - /obj/item/pen = 75, \ - /obj/item/stack/rods = 50 - ) - - duration = DRILL_DURATION - -/datum/surgery_step/cavity/make_space/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !affected.cavity - -/datum/surgery_step/cavity/make_space/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts making some space inside [target]'s [affected.cavity_name] cavity with \the [tool].", \ - "You start making some space inside [target]'s [affected.cavity_name] cavity with \the [tool]." ) - target.custom_pain("The pain in your chest is living hell!",1,affecting = affected) - affected.cavity = 1 - ..() - -/datum/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("[user] makes some space inside [target]'s [affected.cavity_name] cavity with \the [tool].", \ - "You make some space inside [target]'s [affected.cavity_name] cavity with \the [tool]." ) - -////////////////////////////////////////////////////////////////// -// implant cavity sealing surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/cavity/close_space - priority = 2 - allowed_tools = list( - /obj/item/cautery = 100, \ - /obj/item/clothing/mask/smokable/cigarette = 75, \ - /obj/item/flame/lighter = 50, \ - /obj/item/weldingtool = 25 - ) - - duration = CAUTERIZE_DURATION - -/datum/surgery_step/cavity/close_space/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && affected.cavity - -/datum/surgery_step/cavity/close_space/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts mending [target]'s [affected.cavity_name] cavity wall with \the [tool].", \ - "You start mending [target]'s [affected.cavity_name] cavity wall with \the [tool]." ) - target.custom_pain("The pain in your chest is living hell!",1,affecting = affected) - affected.cavity = 0 - ..() - -/datum/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - user.visible_message("[user] mends [target]'s [affected.cavity_name] cavity walls with \the [tool].", \ - "You mend [target]'s [affected.cavity_name] cavity walls with \the [tool]." ) - -////////////////////////////////////////////////////////////////// -// implanting surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/cavity/place_item - priority = 0 - allowed_tools = list(/obj/item = 100) - - duration = ATTACH_DURATION - -/datum/surgery_step/cavity/place_item/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(istype(user,/mob/living/silicon/robot)) - return FALSE - if(affected && affected.cavity) - var/max_volume = base_storage_capacity(affected.cavity_max_w_class) + affected.internal_organs_size - - for(var/obj/item/organ/internal/org in affected.internal_organs) - max_volume -= org.get_storage_cost() - - if(tool.get_storage_cost() > max_volume || affected.cavity_max_w_class < tool.w_class) - to_chat(user, SPAN_WARNING("\The [tool] is too big for [affected.cavity_name] cavity.")) - return SURGERY_FAILURE - - var/total_volume = tool.get_storage_cost() - for(var/obj/item/I in affected.implants) - if(istype(I,/obj/item/implant)) - continue - total_volume += I.get_storage_cost() - if(total_volume > max_volume) - to_chat(user, "There isn't enough space left in [affected.cavity_name] cavity for [tool].") - return FALSE - return TRUE - - -/datum/surgery_step/cavity/place_item/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts putting \the [tool] inside [target]'s [affected.cavity_name] cavity.", \ - "You start putting \the [tool] inside [target]'s [affected.cavity_name] cavity." ) - target.custom_pain("The pain in your chest is living hell!",1,affecting = affected) - playsound(target.loc, 'sound/effects/squelch1.ogg', 25, 1) - ..() - -/datum/surgery_step/cavity/place_item/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/chest/affected = target.get_organ(target_zone) - if(!user.drop(tool, affected)) - return - user.visible_message("[user] puts \the [tool] inside [target]'s [affected.cavity_name] cavity.", \ - "You put \the [tool] inside [target]'s [affected.cavity_name] cavity." ) - if(tool.w_class > affected.cavity_max_w_class/2 && prob(50) && !BP_IS_ROBOTIC(affected) && affected.sever_artery()) - to_chat(user, "You tear some blood vessels trying to fit such a big object in this cavity.") - affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1, affecting = affected) - affected.implants += tool - affected.cavity = 0 - -////////////////////////////////////////////////////////////////// -// implant removal surgery step -////////////////////////////////////////////////////////////////// -/datum/surgery_step/cavity/implant_removal - allowed_tools = list( - /obj/item/hemostat = 100, \ - /obj/item/wirecutters = 75, \ - /obj/item/material/kitchen/utensil/fork = 20 - ) - - duration = CLAMP_DURATION - -/datum/surgery_step/cavity/implant_removal/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) - return FALSE - if(!BP_IS_ROBOTIC(affected)) - return affected.open() >= SURGERY_RETRACTED - else - return affected.hatch_state == HATCH_OPENED - -/datum/surgery_step/cavity/implant_removal/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message("[user] starts poking around inside [target]'s [affected.name] with \the [tool].", \ - "You start poking around inside [target]'s [affected.name] with \the [tool]" ) - target.custom_pain("The pain in your [affected.name] is living hell!",1,affecting = affected) - ..() - -/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/exposed = 0 - if(affected.open() >= (affected.encased ? SURGERY_ENCASED : SURGERY_RETRACTED)) - exposed = 1 - if(BP_IS_ROBOTIC(affected) && affected.hatch_state == HATCH_OPENED) - exposed = 1 - - var/find_prob = 0 - var/list/loot = list() - if(exposed) - loot = affected.implants - else - for(var/datum/wound/wound in affected.wounds) - loot |= wound.embedded_objects - find_prob += 50 - - if (loot.len) - - var/obj/item/obj = pick(loot) - - if(istype(obj,/obj/item/implant)) - var/obj/item/implant/imp = obj - if (imp.islegal()) - find_prob +=60 - else - find_prob +=40 - 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 - for(var/datum/wound/wound in affected.wounds) - if(obj in wound.embedded_objects) - wound.embedded_objects -= obj - break - - BITSET(target.hud_updateflag, IMPLOYAL_HUD) - - obj.dropInto(target.loc) - obj.add_blood(target) - obj.update_icon() - if(istype(obj,/obj/item/implant)) - var/obj/item/implant/imp = obj - imp.removed() - playsound(target.loc, 'sound/effects/squelch1.ogg', 15, 1) - 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." ) - 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]." ) - -/datum/surgery_step/cavity/implant_removal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - ..() - var/obj/item/organ/external/affected = target.get_organ(target_zone) - for(var/obj/item/implant/imp in affected.implants) - var/fail_prob = 10 - fail_prob += 100 - tool_quality(tool) - if (prob(fail_prob)) - user.visible_message("Something beeps inside [target]'s [affected.name]!") - playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3) - spawn(25) - imp.activate() - From e22a0838f43599ef76be09f75a4d7b482e6bae48 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:51:18 +0300 Subject: [PATCH 24/37] fix logic in surgery status --- code/datums/surgery/surgery_status.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/datums/surgery/surgery_status.dm b/code/datums/surgery/surgery_status.dm index b76f3683ebb..13fa88bee77 100644 --- a/code/datums/surgery/surgery_status.dm +++ b/code/datums/surgery/surgery_status.dm @@ -15,7 +15,8 @@ /datum/surgery_status/proc/start_surgery(obj/item/organ/target_organ, target_zone) LAZYADD(ongoing_steps, target_zone) - LAZYADDASSOC(operated_organs, target_zone, target_organ) + operated_organs[target_zone] = target_organ /datum/surgery_status/proc/stop_surgery(target_zone) + LAZYREMOVE(ongoing_steps, target_zone) operated_organs[target_zone] = null From 5a87b05cf4374163d9aaef4cbdfeb319b061c790 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:51:49 +0300 Subject: [PATCH 25/37] add comments --- code/datums/surgery/surgery_step.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/datums/surgery/surgery_step.dm b/code/datums/surgery/surgery_step.dm index 3853b6b34cc..98e0139df8e 100644 --- a/code/datums/surgery/surgery_step.dm +++ b/code/datums/surgery/surgery_step.dm @@ -73,6 +73,7 @@ var/obj/item/organ/target_organ = pick_target_organ(user, target, target_zone) + // Integrated circuits can't change tool during organ picking step, but spessmen can. var/mob/possible_mob = user if(istype(possible_mob)) var/obj/item/active_item = possible_mob.get_active_item() @@ -83,7 +84,7 @@ return FALSE // At this point we can access selected organ via `surgery_status`. - target.surgery_status.start_surgery(target_organ, parent_zone) + target.surgery_status.start_surgery(target_organ || parent_organ, parent_zone) initiate(parent_organ, target_organ, target, tool, user) target.surgery_status.stop_surgery(parent_zone) From d40717bf4bf43e652cd9efdbcaefb4a92c3cced4 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 01:52:07 +0300 Subject: [PATCH 26/37] include surgery step files --- baystation12.dme | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/baystation12.dme b/baystation12.dme index 58dc3f86259..7fc7646fb29 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -455,8 +455,12 @@ #include "code\datums\surgery\surgery_item.dm" #include "code\datums\surgery\surgery_status.dm" #include "code\datums\surgery\surgery_step.dm" +#include "code\datums\surgery\steps\bone.dm" #include "code\datums\surgery\steps\face.dm" +#include "code\datums\surgery\steps\generic.dm" #include "code\datums\surgery\steps\implant.dm" +#include "code\datums\surgery\steps\internal.dm" +#include "code\datums\surgery\steps\limb.dm" #include "code\datums\surgery\steps\misc.dm" #include "code\datums\surgery\steps\robotic.dm" #include "code\datums\trading\_trading_defines.dm" From ae39346145b240d7b66b7f1535dcc6db24a515f1 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 02:07:59 +0300 Subject: [PATCH 27/37] probably make integrated circuits work --- baystation12.dme | 1 + .../subtypes/medical.dm | 49 ++----------------- 2 files changed, 6 insertions(+), 44 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index 7fc7646fb29..9cdcbd7fdd1 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1869,6 +1869,7 @@ #include "code\modules\integrated_electronics\subtypes\lists.dm" #include "code\modules\integrated_electronics\subtypes\logic.dm" #include "code\modules\integrated_electronics\subtypes\manipulation.dm" +#include "code\modules\integrated_electronics\subtypes\medical.dm" #include "code\modules\integrated_electronics\subtypes\memory.dm" #include "code\modules\integrated_electronics\subtypes\mining.dm" #include "code\modules\integrated_electronics\subtypes\output.dm" diff --git a/code/modules/integrated_electronics/subtypes/medical.dm b/code/modules/integrated_electronics/subtypes/medical.dm index 8b1931cce31..ab16c57f288 100644 --- a/code/modules/integrated_electronics/subtypes/medical.dm +++ b/code/modules/integrated_electronics/subtypes/medical.dm @@ -11,7 +11,6 @@ #define SURGERY_RETRACTOR 5 #define SURGERY_CAUTERY 6 #define SURGERY_DRILL 7 -#define SURGERY_FAILED_STATE -1337 /obj/item/integrated_circuit/medical category_text = "Medical" @@ -64,7 +63,7 @@ QDEL_NULL(st) if(istype(I, /obj/item/organfixer/advanced)) operation_intent = SURGERY_ORGAN_HEAL - st = new /datum/surgery_step/internal/fix_organ_multiple() + st = new /datum/surgery_step/internal/fix_organ/multiple() /obj/item/integrated_circuit/medical/surgery_device/get_selected_zone() return selected_zone @@ -132,12 +131,8 @@ if(!selected_zone || !(selected_zone in BP_ALL_LIMBS)) activate_pin(3) return - if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. - activate_pin(3) - return - var/status = do_int_surgery(H) - if(status && !(status == SURGERY_FAILURE || status == SURGERY_BLOCKED)) + if(do_int_surgery(H)) var/atom/A = get_object() A.investigate_log("made some operation on ([H]) with [src].", INVESTIGATE_CIRCUIT) activate_pin(2) @@ -151,23 +146,9 @@ for(var/datum/surgery_step/S in GLOB.surgery_steps) if(istype(S, /datum/surgery_step/internal) && S.type != st?.type) continue - var/status = do_real_surgery(M, S) - if(status != SURGERY_FAILED_STATE) - return status + return S.do_step(get_object(), M, instrument, selected_zone) return FALSE -/obj/item/integrated_circuit/medical/surgery_device/proc/do_real_surgery(mob/living/carbon/M, datum/surgery_step/S, use_integrated_circuit_can_use_check = FALSE, obj/item/organ/organ) - check if tool is right or close enough and if this step is possible - var/obj/item/user = get_object() - if(S.tool_quality(instrument)) - var/step_is_valid - if(use_integrated_circuit_can_use_check) - step_is_valid = can_use(M, organ, selected_zone) - else - step_is_valid = S.can_use(user, M, selected_zone, instrument) - if(step_is_valid && S.is_valid_target(M)) - return S.do_surgery_process(M, user, selected_zone, instrument, step_is_valid) - return SURGERY_FAILED_STATE // for checks... /* SUBTYPES. */ @@ -232,9 +213,6 @@ if(!selected_zone || !(selected_zone in BP_ALL_LIMBS)) activate_pin(3) return - if(selected_zone in H.op_stage.in_progress) //Can't operate on someone repeatedly. - activate_pin(3) - return if(operation_intent == SURGERY_ORGAN_INSERT) E = H.organs_by_name[O.parent_organ] else @@ -243,8 +221,7 @@ activate_pin(3) return - var/status = do_int_surgery(H) - if(status && !(status == SURGERY_FAILURE || status == SURGERY_BLOCKED)) + if(do_int_surgery(H)) organ = null var/atom/A = get_object() A.investigate_log("made some operation on ([H]) with [src].", INVESTIGATE_CIRCUIT) @@ -252,20 +229,6 @@ else activate_pin(3) -/obj/item/integrated_circuit/medical/surgery_device/internal/do_int_surgery(mob/living/carbon/M) - var/status = do_real_surgery(M, st, TRUE, organ) - if(status != SURGERY_FAILED_STATE) - return status - return FALSE - -/obj/item/integrated_circuit/medical/surgery_device/internal/can_use(mob/living/carbon/human/target, obj/item/organ/internal/organ, target_zone) - if(operation_intent == SURGERY_ORGAN_INSERT) - return st.can_use(src, target, target_zone, organ) - else - st.ignore_tool = TRUE - st.preselected_organ = organ - return st.can_use(src, target, target_zone, instrument) - /obj/item/integrated_circuit/medical/surgery_device/face name = "plastic surgery device" desc = "This device is a manipulator compatible with surgical instruments used for plastic surgery. While holding such an instrument, it can perform the facial reconstructing operation." @@ -289,8 +252,7 @@ var/mob/living/carbon/human/H = get_pin_data(IC_INPUT, 1) selected_zone = BP_MOUTH - var/status = do_int_surgery(H) - if(status && !(status == SURGERY_FAILURE || status == SURGERY_BLOCKED)) + if(do_int_surgery(H)) var/atom/A = get_object() A.investigate_log("made some operation on ([H]) with [src].", INVESTIGATE_CIRCUIT) activate_pin(2) @@ -605,7 +567,6 @@ #undef SURGERY_ORGAN_HEAL #undef SURGERY_ORGAN_CONNECT #undef SURGERY_ORGAN_DISCONNECT -#undef SURGERY_FAILED_STATE #undef SURGERY_BONEGEL #undef SURGERY_BONESET #undef SURGERY_BONESET_ULTRA From 6b604f5ac275206d782513e1f6dc3544d2375f23 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 15:15:42 +0300 Subject: [PATCH 28/37] fix integrated circuits not performing operations --- code/datums/surgery/steps/internal.dm | 2 +- code/modules/integrated_electronics/subtypes/medical.dm | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/code/datums/surgery/steps/internal.dm b/code/datums/surgery/steps/internal.dm index 1f7f2f130cb..25af446f547 100644 --- a/code/datums/surgery/steps/internal.dm +++ b/code/datums/surgery/steps/internal.dm @@ -371,7 +371,7 @@ /** * Fixes chosen organ using organ fixer. */ -/datum/surgery_step/internal/fix_organ/default/default +/datum/surgery_step/internal/fix_organ/default duration = ORGAN_FIX_DURATION allowed_tools = list( diff --git a/code/modules/integrated_electronics/subtypes/medical.dm b/code/modules/integrated_electronics/subtypes/medical.dm index ab16c57f288..60d0bdf515d 100644 --- a/code/modules/integrated_electronics/subtypes/medical.dm +++ b/code/modules/integrated_electronics/subtypes/medical.dm @@ -146,7 +146,11 @@ for(var/datum/surgery_step/S in GLOB.surgery_steps) if(istype(S, /datum/surgery_step/internal) && S.type != st?.type) continue - return S.do_step(get_object(), M, instrument, selected_zone) + + if(!S.do_step(get_object(), M, instrument, selected_zone)) + continue + + return TRUE return FALSE /* @@ -190,7 +194,7 @@ st = new /datum/surgery_step/internal/attach_organ() else if(istype(I, /obj/item/organfixer)) operation_intent = SURGERY_ORGAN_HEAL - st = new /datum/surgery_step/internal/fix_organ() + st = new /datum/surgery_step/internal/fix_organ/default() else if(istype(I, /obj/item/reagent_containers/dropper)) operation_intent = SURGERY_ORGAN_TREAT st = new /datum/surgery_step/internal/treat_necrosis() From 669e39e0270482a01a8c35e527739291ff07c792 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Wed, 25 Oct 2023 15:41:17 +0300 Subject: [PATCH 29/37] add fluff to some surgery errors --- code/datums/surgery/steps/bone.dm | 9 +---- code/datums/surgery/steps/generic.dm | 22 +++++++++-- code/datums/surgery/steps/internal.dm | 54 ++++++++++++++------------- code/datums/surgery/steps/limb.dm | 6 ++- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/code/datums/surgery/steps/bone.dm b/code/datums/surgery/steps/bone.dm index aa562c6b353..4be420e3cea 100644 --- a/code/datums/surgery/steps/bone.dm +++ b/code/datums/surgery/steps/bone.dm @@ -7,14 +7,7 @@ shock_level = 20 /datum/surgery_step/bone/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) - . = ..() - if(!.) - return . - - if(BP_IS_ROBOTIC(parent_organ)) - return FALSE - - return parent_organ.open() >= SURGERY_RETRACTED + return (..() && !BP_IS_ROBOTIC(parent_organ) && parent_organ.open() >= SURGERY_RETRACTED) /** * Bone glueing step. diff --git a/code/datums/surgery/steps/generic.dm b/code/datums/surgery/steps/generic.dm index 3cf7bf8d407..770451869e6 100644 --- a/code/datums/surgery/steps/generic.dm +++ b/code/datums/surgery/steps/generic.dm @@ -102,7 +102,15 @@ ) /datum/surgery_step/generic/cut_open/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) - return (..() && !parent_organ.open()) + . = ..() + if(!.) + return + + if(parent_organ.open()) + target.show_splash_text(user, "incision is already present!") + return FALSE + + return TRUE /datum/surgery_step/generic/cut_open/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_preop(user, @@ -197,7 +205,7 @@ /obj/item/scalpel/manager = 100 ) -/datum/surgery_step/generic/incision_manager/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) +/datum/surgery_step/generic/incision_manager/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) return (..() && (parent_organ.open() == SURGERY_CLOSED || parent_organ.open() == SURGERY_OPEN)) /datum/surgery_step/generic/incision_manager/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) @@ -402,7 +410,15 @@ ) /datum/surgery_step/generic/amputate/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) - return (..() && !parent_organ.open() && (parent_organ.limb_flags & ORGAN_FLAG_CAN_AMPUTATE)) + . = ..() + if(!.) + return + + if(!parent_organ.open()) + target.show_splash_text(user, "cauterize incisions first") + return FALSE + + return parent_organ.limb_flags & ORGAN_FLAG_CAN_AMPUTATE /datum/surgery_step/generic/amputate/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_preop(user, diff --git a/code/datums/surgery/steps/internal.dm b/code/datums/surgery/steps/internal.dm index 25af446f547..a61a704d291 100644 --- a/code/datums/surgery/steps/internal.dm +++ b/code/datums/surgery/steps/internal.dm @@ -10,7 +10,7 @@ /datum/surgery_step/internal/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) return target.surgery_status.operated_organs[get_parent_zone(target_zone)] -/datum/surgery_step/internal/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) +/datum/surgery_step/internal/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) . = ..() if(!.) return . @@ -55,12 +55,8 @@ return selected_organ -/datum/surgery_step/internal/attach_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) - . = ..() - if(!.) - return - - return !BP_IS_ROBOTIC(parent_organ) +/datum/surgery_step/internal/attach_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && !BP_IS_ROBOTIC(parent_organ)) /datum/surgery_step/internal/attach_organ/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_preop(user, @@ -103,12 +99,8 @@ /obj/item/material/shard = 50 ) -/datum/surgery_step/internal/detatch_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) - . = ..() - if(!.) - return . - - return !BP_IS_ROBOTIC(parent_organ) +/datum/surgery_step/internal/detatch_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && !BP_IS_ROBOTIC(parent_organ)) /datum/surgery_step/internal/detatch_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) var/list/attached_organs = list() @@ -231,7 +223,7 @@ /obj/item/organ/internal = 100 ) -/datum/surgery_step/internal/replace_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) +/datum/surgery_step/internal/replace_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) . = ..() if(!.) return @@ -241,19 +233,23 @@ return FALSE if(BP_IS_ROBOTIC(parent_organ) && !BP_IS_ROBOTIC(target_organ)) - return FALSE // organic to robotic is bad + target.show_splash_text(user, "organic organ can't be connected to a robotic body!") + return FALSE if(!target.species) CRASH("Target ([target]) of surgery [type] has no species!") if(target_organ.organ_tag == BP_POSIBRAIN && !target.species.has_organ[BP_POSIBRAIN]) - return FALSE // Posibrain to synth body is bad + target.show_splash_text(user, "this type of body isn't supported!") + return FALSE if(target_organ.damage > (target_organ.max_damage * 0.75)) - return FALSE // Too damageed + target.show_splash_text(user, "organ is too damaged!") + return FALSE if(target_organ.w_class > parent_organ.cavity_max_w_class) - return FALSE // Too big + target.show_splash_text(user, "organ won't fit inside!") + return FALSE var/obj/item/organ/internal/O = target.internal_organs_by_name[target_organ.organ_tag] if(O && (O.parent_organ == parent_organ.organ_tag || istype(target_organ, /obj/item/organ/internal/stack))) @@ -268,7 +264,8 @@ for(var/obj/item/I in parent_organ.internal_organs) used_volume += I.get_storage_cost() if((base_storage_capacity(parent_organ.cavity_max_w_class) + parent_organ.internal_organs_size) < used_volume + target_organ.get_storage_cost()) - return FALSE // There's no space... + target.show_splash_text(user, "not enough space!") + return FALSE return TRUE @@ -318,7 +315,7 @@ /datum/surgery_step/internal/fix_organ duration = ORGAN_FIX_DURATION -/datum/surgery_step/internal/fix_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) +/datum/surgery_step/internal/fix_organ/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) return (istype(parent_organ) && !BP_IS_ROBOTIC(parent_organ)) /datum/surgery_step/internal/fix_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) @@ -364,7 +361,8 @@ return FALSE if(!target_organ.can_recover()) - return FALSE // Destroyed organ + target.show_splash_text(user, "organ is damaged beyond recover!") + return FALSE return !!target_organ.damage @@ -390,7 +388,11 @@ if(!. && !organ_fixer.emagged) return FALSE - return organ_fixer.gel_amt > 0 + if(organ_fixer.gel_amt == 0) + target.show_splash_text(user, "not enough gel!") + return FALSE + + return TRUE /datum/surgery_step/internal/fix_organ/default/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_preop(user, @@ -478,7 +480,8 @@ var/obj/item/stack/medical/M = tool if(M.amount < 1) - return FALSE // Nothing left + target.show_splash_text(user, "not enough medicine to complete this step!") + return FALSE return TRUE @@ -550,7 +553,7 @@ /obj/item/organfixer/advanced = 100 ) -/datum/surgery_step/internal/fix_organ/multiple/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) +/datum/surgery_step/internal/fix_organ/multiple/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) . = ..() if(!.) return @@ -560,6 +563,7 @@ return FALSE if(organ_fixer.gel_amt == 0) + target.show_splash_text(user, "not enough gel!") return FALSE for(var/obj/item/organ/internal/I in parent_organ.internal_organs) @@ -666,7 +670,7 @@ /obj/item/reagent_containers/vessel/bucket = 50 ) -/datum/surgery_step/internal/treat_necrosis/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool) +/datum/surgery_step/internal/treat_necrosis/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) return (..() && !BP_IS_ROBOTIC(parent_organ)) /datum/surgery_step/internal/treat_necrosis/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) diff --git a/code/datums/surgery/steps/limb.dm b/code/datums/surgery/steps/limb.dm index 4df87aec38d..079750383e8 100644 --- a/code/datums/surgery/steps/limb.dm +++ b/code/datums/surgery/steps/limb.dm @@ -33,10 +33,12 @@ return FALSE var/obj/item/organ/external/P = target.get_organ(E.parent_organ) - if(isnull(P) || P.is_stump()) + if(!isnull(P) || P.is_stump()) + target.show_splash_text(user, "limb is already present!") return FALSE if(BP_IS_ROBOTIC(P) && !BP_IS_ROBOTIC(E)) + target.show_splash_text(user, "organic limb can't be connected to a robotic body!") return FALSE return !isnull(target.species.has_limbs["[E.organ_tag]"]) @@ -98,7 +100,7 @@ if(parent_organ.is_stump()) return FALSE - return (parent_organ.status & ORGAN_CUT_AWAY) + return parent_organ.status & ORGAN_CUT_AWAY /datum/surgery_step/limb/connect/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_success(user, From cf3e0e1de11ca28dd697795ef36b93d24b0248e2 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Thu, 26 Oct 2023 22:10:25 +0300 Subject: [PATCH 30/37] make Toby hate me less, at least i hope so --- code/_helpers/surgery.dm | 24 --------- code/_onclick/item_attack.dm | 6 +-- code/datums/surgery/_defines.dm | 2 + code/datums/surgery/steps/face.dm | 3 ++ code/datums/surgery/steps/generic.dm | 51 ++++++++----------- code/datums/surgery/steps/implant.dm | 4 +- code/datums/surgery/steps/internal.dm | 33 +++++++----- code/datums/surgery/steps/limb.dm | 6 +-- code/datums/surgery/steps/robotic.dm | 4 +- code/datums/surgery/surgery_item.dm | 8 ++- code/datums/surgery/surgery_step.dm | 17 ++++--- .../mob/living/carbon/human/human_helpers.dm | 27 ++++++++++ 12 files changed, 100 insertions(+), 85 deletions(-) diff --git a/code/_helpers/surgery.dm b/code/_helpers/surgery.dm index 505831159d0..14b6169373a 100644 --- a/code/_helpers/surgery.dm +++ b/code/_helpers/surgery.dm @@ -15,30 +15,6 @@ GLOB.surgery_steps.Swap(i, gap + i) swapped = TRUE -/// Check if mob is lying down on something we can operate him on. -/proc/can_operate(mob/living/carbon/M, mob/living/carbon/user) - var/turf/T = get_turf(M) - if(locate(/obj/machinery/optable, T)) - . = TRUE - if(locate(/obj/structure/bed, T)) - . = TRUE - if(locate(/obj/structure/table, T)) - . = TRUE - if(locate(/obj/effect/rune/, T)) - . = TRUE - - if(M == user) - var/hitzone = check_zone(user.zone_sel.selecting) - var/list/badzones = list(BP_HEAD) - if(user.hand) - badzones += BP_L_ARM - badzones += BP_L_HAND - else - badzones += BP_R_ARM - badzones += BP_R_HAND - if(hitzone in badzones) - return FALSE - /// Creates and "centers" organ image for later use inside radial menu. /proc/agjust_organ_image(obj/item/organ/O) var/image/I = image(icon = O.icon, icon_state = O.icon_state) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 12d39adae99..a15c6ac236f 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -142,9 +142,6 @@ avoid code duplication. This includes items that may sometimes act as a standard if(!ismob(user)) return FALSE - if(can_operate(src, user) && I.do_surgery(src, user)) - return TRUE - return I.attack(src, user, user.zone_sel.selecting) /mob/living/carbon/human/attackby(obj/item/I, mob/user) @@ -156,4 +153,7 @@ avoid code duplication. This includes items that may sometimes act as a standard else if(devour(I)) return 1 + if(I.do_surgery(src, user)) + return TRUE + return ..() diff --git a/code/datums/surgery/_defines.dm b/code/datums/surgery/_defines.dm index f14419730a6..b8366bb555e 100644 --- a/code/datums/surgery/_defines.dm +++ b/code/datums/surgery/_defines.dm @@ -1,3 +1,5 @@ +#define SURGERY_FAILURE -1 + /// Causes hands to become bloody. #define BLOODY_HANDS (1 << 0) /// Causes body to become bloody. diff --git a/code/datums/surgery/steps/face.dm b/code/datums/surgery/steps/face.dm index 25887989067..e3bb07d8e40 100644 --- a/code/datums/surgery/steps/face.dm +++ b/code/datums/surgery/steps/face.dm @@ -22,6 +22,9 @@ /obj/item/material/shard = 50 ) +/datum/surgery_step/generic/cut_face/check_zone(target_zone) + return (..() && target_zone == BP_MOUTH) + /datum/surgery_step/generic/cut_face/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) return (..() && target.surgery_status.face == 0) diff --git a/code/datums/surgery/steps/generic.dm b/code/datums/surgery/steps/generic.dm index 770451869e6..c8779a300ad 100644 --- a/code/datums/surgery/steps/generic.dm +++ b/code/datums/surgery/steps/generic.dm @@ -47,7 +47,8 @@ return . if(!parent_organ.get_incision(TRUE)) - return FALSE + target.show_splash_text(user, "no incisions that can be closed cleanly!") + return SURGERY_FAILURE if(parent_organ.is_stump()) return parent_organ.status & ORGAN_ARTERY_CUT @@ -86,13 +87,19 @@ ) parent_organ.take_external_damage(0, 3, used_weapon = tool) - /** - * Default icision with scalpel, nothing extra. + * Default incision creation step, does nothing. */ -/datum/surgery_step/generic/cut_open +/datum/surgery_step/generic/cut duration = CUT_DURATION +/datum/surgery_step/generic/cut/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + return (..() && !parent_organ.open()) + +/** + * Default icision with scalpel, nothing extra. + */ +/datum/surgery_step/generic/cut/default allowed_tools = list( /obj/item/scalpel = 100, /obj/item/material/knife = 75, @@ -101,18 +108,7 @@ /obj/item/material/shard = 50 ) -/datum/surgery_step/generic/cut_open/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) - . = ..() - if(!.) - return - - if(parent_organ.open()) - target.show_splash_text(user, "incision is already present!") - return FALSE - - return TRUE - -/datum/surgery_step/generic/cut_open/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) +/datum/surgery_step/generic/cut/default/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_preop(user, "[user] starts the incision on [target]'s [parent_organ] with \the [tool].", "You start the incision on [target]'s [parent_organ] with \the [tool]." @@ -124,7 +120,7 @@ ) return ..() -/datum/surgery_step/generic/cut_open/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) +/datum/surgery_step/generic/cut/default/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_success(user, "[user] has made an incision on [target]'s [parent_organ] with \the [tool].", "You have made an incision on [target]'s [parent_organ] with \the [tool]." @@ -132,7 +128,7 @@ parent_organ.createwound(CUT, parent_organ.min_broken_damage / 2, 1) playsound(target.loc, 'sound/weapons/bladeslice.ogg', 15, 1) -/datum/surgery_step/generic/cut_open/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) +/datum/surgery_step/generic/cut/default/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_failure(user, "[user]'s hand slips, slicing open [target]'s [parent_organ] in the wrong place with \the [tool]!", "Your hand slips, slicing open [target]'s [parent_organ] in the wrong place with \the [tool]!" @@ -147,9 +143,8 @@ /** * Incision made with laser scalpel, clamps bleeders. */ -/datum/surgery_step/generic/cut_with_laser +/datum/surgery_step/generic/cut/laser priority = 2 - duration = CUT_DURATION allowed_tools = list( /obj/item/scalpel/laser3 = 100, @@ -158,10 +153,7 @@ /obj/item/melee/energy/sword/one_hand = 50 ) -/datum/surgery_step/generic/cut_with_laser/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) - return (..() && !parent_organ.open()) - -/datum/surgery_step/generic/cut_with_laser/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) +/datum/surgery_step/generic/cut/laser/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_preop(user, "[user] starts the bloodless incision on [target]'s [parent_organ] with \the [tool].", "You start the bloodless incision on [target]'s [parent_organ] with \the [tool]." @@ -173,7 +165,7 @@ ) return ..() -/datum/surgery_step/generic/cut_with_laser/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) +/datum/surgery_step/generic/cut/laser/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_success(user, "[user] has made a bloodless incision on [target]'s [parent_organ] with \the [tool].", "You have made a bloodless incision on [target]'s [parent_organ] with \the [tool].", @@ -182,7 +174,7 @@ parent_organ.clamp_organ() spread_germs_to_organ(user, parent_organ) -/datum/surgery_step/generic/cut_with_laser/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) +/datum/surgery_step/generic/cut/laser/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_failure(user, "[user]'s hand slips as the blade sputters, searing a long gash in [target]'s [parent_organ] with \the [tool]!", "Your hand slips as the blade sputters, searing a long gash in [target]'s [parent_organ] with \the [tool]!" @@ -347,7 +339,6 @@ * Saws off bones, covering interal organs. */ /datum/surgery_step/generic/saw - can_infect = TRUE delicate = TRUE blood_level = BLOODY_HANDS shock_level = 40 @@ -414,9 +405,9 @@ if(!.) return - if(!parent_organ.open()) - target.show_splash_text(user, "cauterize incisions first") - return FALSE + if(parent_organ.open()) + target.show_splash_text(user, "can't get a clean cut due to present incisions!") + return SURGERY_FAILURE return parent_organ.limb_flags & ORGAN_FLAG_CAN_AMPUTATE diff --git a/code/datums/surgery/steps/implant.dm b/code/datums/surgery/steps/implant.dm index 2df5cadb0da..e8ae13e869e 100644 --- a/code/datums/surgery/steps/implant.dm +++ b/code/datums/surgery/steps/implant.dm @@ -14,7 +14,7 @@ if(BP_IS_ROBOTIC(parent_organ)) return parent_organ.hatch_state == HATCH_OPENED - return parent_organ.open() >= (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED) + return (parent_organ.open() >= (parent_organ.encased ? SURGERY_ENCASED : SURGERY_RETRACTED)) /datum/surgery_step/cavity/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_failure(user, @@ -125,7 +125,7 @@ if(tool.get_storage_cost() > max_volume || parent_organ.cavity_max_w_class < tool.w_class) target.show_splash_text(user, "tool is too big!") - return FALSE + return SURGERY_FAILURE var/total_volume = tool.get_storage_cost() for(var/obj/item/I in parent_organ.implants) diff --git a/code/datums/surgery/steps/internal.dm b/code/datums/surgery/steps/internal.dm index a61a704d291..bfe955c90b0 100644 --- a/code/datums/surgery/steps/internal.dm +++ b/code/datums/surgery/steps/internal.dm @@ -4,8 +4,9 @@ /datum/surgery_step/internal can_infect = FALSE blood_level = BLOODY_HANDS - shock_level = 40 delicate = TRUE + shock_level = 40 + priority = 2 /datum/surgery_step/internal/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) return target.surgery_status.operated_organs[get_parent_zone(target_zone)] @@ -234,26 +235,27 @@ if(BP_IS_ROBOTIC(parent_organ) && !BP_IS_ROBOTIC(target_organ)) target.show_splash_text(user, "organic organ can't be connected to a robotic body!") - return FALSE + return SURGERY_FAILURE if(!target.species) CRASH("Target ([target]) of surgery [type] has no species!") if(target_organ.organ_tag == BP_POSIBRAIN && !target.species.has_organ[BP_POSIBRAIN]) target.show_splash_text(user, "this type of body isn't supported!") - return FALSE + return SURGERY_FAILURE if(target_organ.damage > (target_organ.max_damage * 0.75)) target.show_splash_text(user, "organ is too damaged!") - return FALSE + return SURGERY_FAILURE if(target_organ.w_class > parent_organ.cavity_max_w_class) target.show_splash_text(user, "organ won't fit inside!") - return FALSE + return SURGERY_FAILURE var/obj/item/organ/internal/O = target.internal_organs_by_name[target_organ.organ_tag] if(O && (O.parent_organ == parent_organ.organ_tag || istype(target_organ, /obj/item/organ/internal/stack))) - return FALSE + target.show_splash_text(user, "stack is already present!") + return SURGERY_FAILURE var/used_volume = 0 for(var/obj/item/I in parent_organ.implants) @@ -265,7 +267,7 @@ used_volume += I.get_storage_cost() if((base_storage_capacity(parent_organ.cavity_max_w_class) + parent_organ.internal_organs_size) < used_volume + target_organ.get_storage_cost()) target.show_splash_text(user, "not enough space!") - return FALSE + return SURGERY_FAILURE return TRUE @@ -362,7 +364,7 @@ if(!target_organ.can_recover()) target.show_splash_text(user, "organ is damaged beyond recover!") - return FALSE + return SURGERY_FAILURE return !!target_organ.damage @@ -386,11 +388,12 @@ return FALSE if(!. && !organ_fixer.emagged) - return FALSE + target.show_splash_text(user, "organ doesn't require any healing!") + return SURGERY_FAILURE if(organ_fixer.gel_amt == 0) target.show_splash_text(user, "not enough gel!") - return FALSE + return SURGERY_FAILURE return TRUE @@ -414,6 +417,9 @@ if(organ_fixer.gel_amt == 0) return + if(organ_fixer.gel_amt > 0) + organ_fixer.gel_amt-- + if(organ_fixer.emagged) announce_success(user, "[user]'s hand slips, getting mess and tearing the inside of [target]'s [internal_organ] with \the [organ_fixer]!", @@ -481,7 +487,7 @@ var/obj/item/stack/medical/M = tool if(M.amount < 1) target.show_splash_text(user, "not enough medicine to complete this step!") - return FALSE + return SURGERY_FAILURE return TRUE @@ -564,7 +570,7 @@ if(organ_fixer.gel_amt == 0) target.show_splash_text(user, "not enough gel!") - return FALSE + return SURGERY_FAILURE for(var/obj/item/organ/internal/I in parent_organ.internal_organs) if(BP_IS_ROBOTIC(I)) @@ -709,7 +715,8 @@ return FALSE if(!target_organ.can_recover() && istype(target_organ, /obj/item/organ/internal/cerebrum/brain)) - return FALSE + target.show_splash_text(user, "organ is damaged beyond recover!") + return SURGERY_FAILURE return TRUE diff --git a/code/datums/surgery/steps/limb.dm b/code/datums/surgery/steps/limb.dm index 079750383e8..cd6d4831e33 100644 --- a/code/datums/surgery/steps/limb.dm +++ b/code/datums/surgery/steps/limb.dm @@ -33,13 +33,13 @@ return FALSE var/obj/item/organ/external/P = target.get_organ(E.parent_organ) - if(!isnull(P) || P.is_stump()) + if(isnull(P) || P.is_stump()) target.show_splash_text(user, "limb is already present!") - return FALSE + return SURGERY_FAILURE if(BP_IS_ROBOTIC(P) && !BP_IS_ROBOTIC(E)) target.show_splash_text(user, "organic limb can't be connected to a robotic body!") - return FALSE + return SURGERY_FAILURE return !isnull(target.species.has_limbs["[E.organ_tag]"]) diff --git a/code/datums/surgery/steps/robotic.dm b/code/datums/surgery/steps/robotic.dm index 2caef89f3db..1c172a3ccd3 100644 --- a/code/datums/surgery/steps/robotic.dm +++ b/code/datums/surgery/steps/robotic.dm @@ -226,11 +226,11 @@ var/obj/item/stack/cable_coil/C = tool if(!istype(C)) - return + return FALSE if(!C.use(3)) target.show_splash_text(user, "not enough coil length!") - return FALSE + return SURGERY_FAILURE return TRUE diff --git a/code/datums/surgery/surgery_item.dm b/code/datums/surgery/surgery_item.dm index 82e234cbec7..1d1e438aa03 100644 --- a/code/datums/surgery/surgery_item.dm +++ b/code/datums/surgery/surgery_item.dm @@ -1,12 +1,16 @@ -/obj/item/proc/do_surgery(mob/living/carbon/target, mob/living/user) +/obj/item/proc/do_surgery(mob/living/carbon/human/target, mob/user) if(!hasorgans(target)) return FALSE if(user.a_intent == I_HURT) return FALSE + if(!target.can_operate(user)) + return FALSE + for(var/datum/surgery_step/S in GLOB.surgery_steps) - if(S.do_step(user, target, src, user.zone_sel.selecting)) + var/status = S.do_step(user, target, src, user.zone_sel.selecting) + if(status || status == SURGERY_FAILURE) return TRUE return FALSE diff --git a/code/datums/surgery/surgery_step.dm b/code/datums/surgery/surgery_step.dm index 98e0139df8e..e49270b180a 100644 --- a/code/datums/surgery/surgery_step.dm +++ b/code/datums/surgery/surgery_step.dm @@ -24,6 +24,9 @@ /** * Performs preop checks and fires step if succeeded. * + * Returns `FALSE` if step requirements weren't met or `SURGERY_FAILURE` + * if any organ checks were failed. + * * Vars: * * user - atom that fired this step. * * target - human mob over which this step would be fired. @@ -65,11 +68,12 @@ return FALSE if(accessible && !check_clothing(target, target_zone)) - return FALSE + return SURGERY_FAILURE var/obj/item/organ/parent_organ = target.get_organ(parent_zone) - if(!check_parent_organ(parent_organ, target, tool)) - return FALSE + var/parent_status = check_parent_organ(parent_organ, target, tool, user) + if(!parent_status || parent_status == SURGERY_FAILURE) + return parent_status var/obj/item/organ/target_organ = pick_target_organ(user, target, target_zone) @@ -78,10 +82,11 @@ if(istype(possible_mob)) var/obj/item/active_item = possible_mob.get_active_item() if(active_item != tool) - return FALSE + return SURGERY_FAILURE - if(!check_target_organ(target_organ, target, tool)) - return FALSE + var/target_status = check_target_organ(target_organ, target, tool, user) + if(!target_status || target_status == SURGERY_FAILURE) + return target_status // At this point we can access selected organ via `surgery_status`. target.surgery_status.start_surgery(target_organ || parent_organ, parent_zone) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index dac2ae9ae7a..c09ead4e21e 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -41,6 +41,33 @@ #undef HUMAN_EATING_NBP_MOUTH #undef HUMAN_EATING_BLOCKED_MOUTH +/// Check whether mob is lying down on something we can operate him on. +/mob/living/carbon/human/proc/can_operate(mob/user) + var/turf/T = get_turf(src) + if(locate(/obj/machinery/optable, T)) + . = TRUE + if(locate(/obj/structure/bed, T)) + . = TRUE + if(locate(/obj/structure/table, T)) + . = TRUE + if(locate(/obj/effect/rune/, T)) + . = TRUE + + + if(src == user) + var/mob/living/carbon/human/H = user // No way it can't be human at this point. + var/hitzone = check_zone(H.zone_sel.selecting) + var/list/badzones = list(BP_HEAD) + if(H.hand) + badzones += BP_L_ARM + badzones += BP_L_HAND + else + badzones += BP_R_ARM + badzones += BP_R_HAND + + if(hitzone in badzones) + return FALSE + /mob/living/carbon/human/proc/update_equipment_vision() flash_protection = 0 equipment_tint_total = 0 From 6f259fb498edd2300bdd6ca0f7d9343c99f15c32 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Thu, 26 Oct 2023 22:31:53 +0300 Subject: [PATCH 31/37] prettify radial menu canceling --- code/datums/surgery/steps/internal.dm | 9 +++------ code/datums/surgery/surgery_step.dm | 2 ++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/code/datums/surgery/steps/internal.dm b/code/datums/surgery/steps/internal.dm index bfe955c90b0..a197446de6a 100644 --- a/code/datums/surgery/steps/internal.dm +++ b/code/datums/surgery/steps/internal.dm @@ -593,15 +593,12 @@ return FALSE /datum/surgery_step/internal/fix_organ/multiple/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) - return null - -/datum/surgery_step/internal/fix_organ/multiple/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) - return TRUE + return target.get_organ(target_zone) /datum/surgery_step/internal/fix_organ/multiple/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) announce_preop(user, - "[user] starts treating damage inside [target]'s [parent_organ] with \the [tool].", - "You start treating damage to inside [target]'s [parent_organ] with \the [tool]." + "[user] starts treating damage to [target]'s [parent_organ] with \the [tool].", + "You start treating damage to [target]'s [parent_organ] with \the [tool]." ) target.custom_pain("The pain in your [parent_organ] is living hell!", 100) return ..() diff --git a/code/datums/surgery/surgery_step.dm b/code/datums/surgery/surgery_step.dm index e49270b180a..de196b6c316 100644 --- a/code/datums/surgery/surgery_step.dm +++ b/code/datums/surgery/surgery_step.dm @@ -76,6 +76,8 @@ return parent_status var/obj/item/organ/target_organ = pick_target_organ(user, target, target_zone) + if(isnull(target_organ)) + return SURGERY_FAILURE // Integrated circuits can't change tool during organ picking step, but spessmen can. var/mob/possible_mob = user From 37f7e619ab3a95807bb5d9795181fad445cc3db8 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:33:22 +0300 Subject: [PATCH 32/37] make internal circuits work --- .../subtypes/medical.dm | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/code/modules/integrated_electronics/subtypes/medical.dm b/code/modules/integrated_electronics/subtypes/medical.dm index 60d0bdf515d..c7cb5315730 100644 --- a/code/modules/integrated_electronics/subtypes/medical.dm +++ b/code/modules/integrated_electronics/subtypes/medical.dm @@ -110,7 +110,7 @@ activate_pin(2) if(3) activate_pin(3) - var/mob/living/carbon/H = get_pin_data(IC_INPUT, 1) + var/mob/living/carbon/human/H = get_pin_data(IC_INPUT, 1) if(!istype(H)) activate_pin(3) return @@ -139,18 +139,21 @@ else activate_pin(3) -/obj/item/integrated_circuit/medical/surgery_device/proc/can_use(mob/living/carbon/human/target, obj/item/organ/internal/organ, target_zone) - return TRUE - -/obj/item/integrated_circuit/medical/surgery_device/proc/do_int_surgery(mob/living/carbon/M) +/obj/item/integrated_circuit/medical/surgery_device/proc/do_int_surgery(mob/living/carbon/human/H) for(var/datum/surgery_step/S in GLOB.surgery_steps) if(istype(S, /datum/surgery_step/internal) && S.type != st?.type) continue - if(!S.do_step(get_object(), M, instrument, selected_zone)) + // `do_step` can return `0` or `-1` if failed, we handle those differently in internal surgery circuit! + var/step_status = S.do_step(get_object(), H, instrument, selected_zone) + if(!step_status) continue + if(step_status == SURGERY_FAILURE) + return FALSE + return TRUE + return FALSE /* @@ -233,6 +236,16 @@ else activate_pin(3) +/obj/item/integrated_circuit/medical/surgery_device/internal/do_int_surgery(mob/living/carbon/human/H) + // We are doing a bit risky stuff here! + H.surgery_status.operated_organs[check_zone(selected_zone)] = organ + . = ..() + if(.) + return + + // If super call returned `FALSE` organ ref wasn't automatically nullified and it WILL cause runtimes in the future. + H.surgery_status.operated_organs[check_zone(selected_zone)] = null + /obj/item/integrated_circuit/medical/surgery_device/face name = "plastic surgery device" desc = "This device is a manipulator compatible with surgical instruments used for plastic surgery. While holding such an instrument, it can perform the facial reconstructing operation." From f51b001536faa6eaad5f5243e35cf111a8c8438b Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:52:29 +0300 Subject: [PATCH 33/37] squash multiline comment --- code/datums/surgery/surgery_status.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/datums/surgery/surgery_status.dm b/code/datums/surgery/surgery_status.dm index 13fa88bee77..e84a518f2ba 100644 --- a/code/datums/surgery/surgery_status.dm +++ b/code/datums/surgery/surgery_status.dm @@ -1,7 +1,5 @@ /datum/surgery_status - /** - * List of zones where surgery steps are currently performed. - */ + /// List of zones where surgery steps are currently performed. var/list/ongoing_steps = list() /** * Associative list of string -> type, where string is zone name and From 2a3bf746eea81247e68a192ae463d3eff0034388 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:28:46 +0300 Subject: [PATCH 34/37] fix zone check in head bone surgery step Co-authored-by: goliath --- code/datums/surgery/steps/bone.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/surgery/steps/bone.dm b/code/datums/surgery/steps/bone.dm index 4be420e3cea..ba8dadfc296 100644 --- a/code/datums/surgery/steps/bone.dm +++ b/code/datums/surgery/steps/bone.dm @@ -63,7 +63,7 @@ ) /datum/surgery_step/bone/mend_bone/check_zone(mob/living/carbon/human/target, target_zone) - return (..() && target_zone == BP_HEAD) + return (..() && target_zone != BP_HEAD) /datum/surgery_step/bone/mend_bone/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) return (..() && parent_organ.stage == 1) From b9db91cbe345c4055f009e77de57f1ae7dd1f944 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:34:41 +0300 Subject: [PATCH 35/37] add defines 'cause idk they're cool --- code/datums/surgery/steps/face.dm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/datums/surgery/steps/face.dm b/code/datums/surgery/steps/face.dm index e3bb07d8e40..40880cdb57f 100644 --- a/code/datums/surgery/steps/face.dm +++ b/code/datums/surgery/steps/face.dm @@ -1,3 +1,5 @@ +#define FACE_SPEED_MOFIFIER 1.25 + /** * Generic face surgry step, does nothing. */ @@ -14,7 +16,7 @@ * Facial tissue cutting step. */ /datum/surgery_step/generic/cut_face - duration = CUT_DURATION * 1.25 + duration = CUT_DURATION * FACE_SPEED_MOFIFIER allowed_tools = list( /obj/item/scalpel = 100, @@ -59,7 +61,7 @@ * Vaocal mending step. */ /datum/surgery_step/face/mend_vocal - duration = CLAMP_DURATION * 1.25 + duration = CLAMP_DURATION * FACE_SPEED_MOFIFIER allowed_tools = list( /obj/item/hemostat = 100, @@ -135,7 +137,7 @@ * Facial cauterization step. */ /datum/surgery_step/face/cauterize - duration = CAUTERIZE_DURATION * 1.25 + duration = CAUTERIZE_DURATION * FACE_SPEED_MOFIFIER allowed_tools = list( /obj/item/cautery = 100, @@ -173,3 +175,5 @@ "Your hand slips, leaving a small burn on [target]'s face with \the [tool]!" ) parent_organ.take_external_damage(0, 4, used_weapon = tool) + +#undef FACE_SPEED_MOFIFIER From 6a0e91dd6444c5d41c64fe7345421eae141d0f4c Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:35:15 +0300 Subject: [PATCH 36/37] remove unhandled tool type --- code/datums/surgery/steps/internal.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/datums/surgery/steps/internal.dm b/code/datums/surgery/steps/internal.dm index a197446de6a..608d0ef9002 100644 --- a/code/datums/surgery/steps/internal.dm +++ b/code/datums/surgery/steps/internal.dm @@ -469,8 +469,7 @@ allowed_tools = list( /obj/item/stack/medical/advanced/bruise_pack= 67, - /obj/item/stack/medical/bruise_pack = 34, - /obj/item/tape_roll = 20 + /obj/item/stack/medical/bruise_pack = 34 ) /datum/surgery_step/internal/fix_organ/ghetto/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) From 19cf19db1eb88e2b664b2c9216e8ae324f87f591 Mon Sep 17 00:00:00 2001 From: Interception&? <137328283+intercepti0n@users.noreply.github.com> Date: Fri, 27 Oct 2023 17:38:27 +0300 Subject: [PATCH 37/37] fix inability to cut limbs and insert organs --- code/datums/surgery/steps/generic.dm | 65 -------------------------- code/datums/surgery/steps/internal.dm | 3 ++ code/datums/surgery/steps/limb.dm | 66 +++++++++++++++++++++++++++ code/datums/surgery/steps/robotic.dm | 6 +-- 4 files changed, 72 insertions(+), 68 deletions(-) diff --git a/code/datums/surgery/steps/generic.dm b/code/datums/surgery/steps/generic.dm index c8779a300ad..0084213eb17 100644 --- a/code/datums/surgery/steps/generic.dm +++ b/code/datums/surgery/steps/generic.dm @@ -385,68 +385,3 @@ used_weapon = tool ) parent_organ.fracture() - -/** - * Amputates limb. - */ -/datum/surgery_step/generic/amputate - duration = AMPUTATION_DURATION - check_stump = FALSE - - allowed_tools = list( - /obj/item/circular_saw = 100, - /obj/item/material/hatchet = 75, - /obj/item/material/twohanded/fireaxe = 85, - /obj/item/gun/energy/plasmacutter = 90 - ) - -/datum/surgery_step/generic/amputate/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) - . = ..() - if(!.) - return - - if(parent_organ.open()) - target.show_splash_text(user, "can't get a clean cut due to present incisions!") - return SURGERY_FAILURE - - return parent_organ.limb_flags & ORGAN_FLAG_CAN_AMPUTATE - -/datum/surgery_step/generic/amputate/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) - announce_preop(user, - "[user] is beginning to amputate [target]'s [parent_organ] with \the [tool].", - "You are beginning to cut through [target]'s [parent_organ.amputation_point] with \the [tool]." - ) - target.custom_pain( - "Your [parent_organ.amputation_point] is being ripped apart!", - 100, - affecting = parent_organ - ) - return ..() - -/datum/surgery_step/generic/amputate/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) - announce_success(user, - "[user] amputates [target]'s [parent_organ] at the [parent_organ.amputation_point] with \the [tool].", - "You amputate [target]'s [parent_organ] with \the [tool]." - ) - parent_organ.droplimb(TRUE, DROPLIMB_EDGE) - -/datum/surgery_step/generic/amputate/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) - announce_failure(user, - "[user]'s hand slips, sawing through the bone in [target]'s [parent_organ] with \the [tool]!", - "Your hand slips, sawwing through the bone in [target]'s [parent_organ] with \the [tool]!" - ) - parent_organ.take_external_damage(30, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) - parent_organ.fracture() - -/datum/surgery_step/generic/amputate/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) - announce_failure(user, - "[user]'s hand slips, sawing through the bone in [target]'s [parent_organ] with \the [tool]!", - "Your hand slips, sawwing through the bone in [target]'s [parent_organ] with \the [tool]!" - ) - parent_organ.take_external_damage( - 30, - 0, - (DAM_SHARP|DAM_EDGE), - used_weapon = tool - ) - parent_organ.fracture() diff --git a/code/datums/surgery/steps/internal.dm b/code/datums/surgery/steps/internal.dm index 608d0ef9002..345c7cb8b40 100644 --- a/code/datums/surgery/steps/internal.dm +++ b/code/datums/surgery/steps/internal.dm @@ -271,6 +271,9 @@ return TRUE +/datum/surgery_step/internal/replace_organ/pick_target_organ(atom/user, mob/living/carbon/human/target, target_zone) + return target.get_organ(target_zone) + /datum/surgery_step/internal/replace_organ/check_target_organ(obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) return TRUE diff --git a/code/datums/surgery/steps/limb.dm b/code/datums/surgery/steps/limb.dm index cd6d4831e33..07ea8b7e16c 100644 --- a/code/datums/surgery/steps/limb.dm +++ b/code/datums/surgery/steps/limb.dm @@ -193,3 +193,69 @@ "Your hand slips, damaging [target]'s flesh!" ) target.apply_damage(10, BRUTE, null, damage_flags = DAM_SHARP) + +/** + * Amputates limb. + */ +/datum/surgery_step/amputate + can_infect = TRUE + shock_level = 10 + duration = AMPUTATION_DURATION + + allowed_tools = list( + /obj/item/circular_saw = 100, + /obj/item/material/hatchet = 75, + /obj/item/material/twohanded/fireaxe = 85, + /obj/item/gun/energy/plasmacutter = 90 + ) + +/datum/surgery_step/amputate/check_parent_organ(obj/item/organ/external/parent_organ, mob/living/carbon/human/target, obj/item/tool, atom/user) + . = ..() + if(!.) + return + + if(parent_organ.open()) + target.show_splash_text(user, "can't get a clean cut due to present incisions!") + return SURGERY_FAILURE + + return parent_organ.limb_flags & ORGAN_FLAG_CAN_AMPUTATE + +/datum/surgery_step/amputate/initiate(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_preop(user, + "[user] is beginning to amputate [target]'s [parent_organ] with \the [tool].", + "You are beginning to cut through [target]'s [parent_organ.amputation_point] with \the [tool]." + ) + target.custom_pain( + "Your [parent_organ.amputation_point] is being ripped apart!", + 100, + affecting = parent_organ + ) + return ..() + +/datum/surgery_step/amputate/success(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_success(user, + "[user] amputates [target]'s [parent_organ] at the [parent_organ.amputation_point] with \the [tool].", + "You amputate [target]'s [parent_organ] with \the [tool]." + ) + parent_organ.droplimb(TRUE, DROPLIMB_EDGE) + +/datum/surgery_step/amputate/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, sawing through the bone in [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, sawwing through the bone in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage(30, 0, (DAM_SHARP|DAM_EDGE), used_weapon = tool) + parent_organ.fracture() + +/datum/surgery_step/amputate/failure(obj/item/organ/external/parent_organ, obj/item/organ/target_organ, mob/living/carbon/human/target, obj/item/tool, mob/user) + announce_failure(user, + "[user]'s hand slips, sawing through the bone in [target]'s [parent_organ] with \the [tool]!", + "Your hand slips, sawwing through the bone in [target]'s [parent_organ] with \the [tool]!" + ) + parent_organ.take_external_damage( + 30, + 0, + (DAM_SHARP|DAM_EDGE), + used_weapon = tool + ) + parent_organ.fracture() diff --git a/code/datums/surgery/steps/robotic.dm b/code/datums/surgery/steps/robotic.dm index 1c172a3ccd3..be8004c28a6 100644 --- a/code/datums/surgery/steps/robotic.dm +++ b/code/datums/surgery/steps/robotic.dm @@ -321,9 +321,9 @@ "Your hand slips, disconnecting \the [tool]." ) -////////////////////////////////////////////////////////////////// -// robotic organ transplant finalization surgery step -////////////////////////////////////////////////////////////////// +/** + * Robotic organ transplant finalization step. + */ /datum/surgery_step/robotics/internal/attach_organ allowed_tools = list( /obj/item/screwdriver = 100