diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index 6fa9d4ec0c..2b75414a7e 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -1157,12 +1157,22 @@ proc/is_hot(obj/item/W as obj)
istype(W, /obj/item/weapon/surgical/bonesetter)
)
-//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.
+// The RNG with table/rollerbeds comes into play in do_surgery() so that fail_step() can be used instead.
/proc/can_operate(mob/living/carbon/M)
- return (M.lying && \
- locate(/obj/machinery/optable, M.loc) || \
- (locate(/obj/structure/bed/roller, M.loc) && prob(75)) || \
- (locate(/obj/structure/table/, M.loc) && prob(66)))
+ return M.lying
+
+// Returns an instance of a valid surgery surface.
+/mob/living/proc/get_surgery_surface()
+ if(!lying)
+ return null // Not lying down means no surface.
+ var/obj/surface = null
+ for(var/obj/O in loc) // Looks for the best surface.
+ if(O.surgery_odds)
+ if(!surface || surface.surgery_odds < O)
+ surface = O
+ if(surface)
+ return surface
/proc/reverse_direction(var/dir)
switch(dir)
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index 4d56d6662d..5696892ddc 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -8,6 +8,7 @@
use_power = 1
idle_power_usage = 1
active_power_usage = 5
+ surgery_odds = 100
var/mob/living/carbon/human/victim = null
var/strapped = 0.0
var/obj/machinery/computer/operating/computer = null
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index 8f91f12b26..1b9d897b99 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -203,6 +203,7 @@
icon = 'icons/obj/rollerbed.dmi'
icon_state = "down"
anchored = 0
+ surgery_odds = 75
/obj/structure/bed/roller/update_icon()
return // Doesn't care about material or anything else.
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 27bf4c0ab7..2d53277590 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -526,9 +526,9 @@ obj/structure/cable/proc/cableColor(var/colorC)
if(!S || S.robotic < ORGAN_ROBOT || S.open == 3)
return ..()
- var/use_amt = min(src.amount, ceil(S.burn_dam/3), 5)
+ var/use_amt = min(src.amount, ceil(S.burn_dam/5), 5)
if(can_use(use_amt))
- if(S.robo_repair(3*use_amt, BURN, "some damaged wiring", src, user))
+ if(S.robo_repair(5*use_amt, BURN, "some damaged wiring", src, user))
src.use(use_amt)
else
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index 38b919823f..b9fe362031 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -1,5 +1,8 @@
/* SURGERY STEPS */
+/obj/
+ var/surgery_odds = 0 // Used for tables/etc which can have surgery done of them.
+
/datum/surgery_step
var/priority = 0 //steps with higher priority would be attempted first
@@ -111,13 +114,29 @@
return 1
M.op_stage.in_progress += zone
S.begin_step(user, M, zone, src) //start on it
- //We had proper tools! (or RNG smiled.) and user did not move or change hands.
- if(prob(S.tool_quality(src)) && do_mob(user, M, rand(S.min_duration, S.max_duration)))
- S.end_step(user, M, zone, src) //finish successfully
- else if ((src in user.contents) && user.Adjacent(M)) //or
- S.fail_step(user, M, zone, src) //malpractice~
- else // This failing silently was a pain.
- user << "You must remain close to your patient to conduct surgery."
+ var/success = TRUE
+
+ // Bad tools make it less likely to succeed.
+ if(!prob(S.tool_quality(src)))
+ success = FALSE
+
+ // Bad or no surface may mean failure as well.
+ var/obj/surface = M.get_surgery_surface()
+ if(!surface || !prob(surface.surgery_odds))
+ success = FALSE
+
+ // Not staying still fails you too.
+ if(success)
+ if(!do_mob(user, M, rand(S.min_duration, S.max_duration)))
+ success = FALSE
+ else
+ to_chat(user, "You must remain close to your patient to conduct surgery.")
+
+ if(success)
+ S.end_step(user, M, zone, src)
+ else
+ S.fail_step(user, M, zone, src)
+
M.op_stage.in_progress -= zone // Clear the in-progress flag.
if (ishuman(M))
var/mob/living/carbon/human/H = M
diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm
index 72cc6dbf8b..db445e9f50 100644
--- a/code/modules/tables/tables.dm
+++ b/code/modules/tables/tables.dm
@@ -8,6 +8,7 @@
climbable = 1
layer = 2.8
throwpass = 1
+ surgery_odds = 66
var/flipped = 0
var/maxhealth = 10
var/health = 10