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