diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm
index 26020c3b2df..10be1785ed2 100644
--- a/code/game/objects/items/weapons/material/knives.dm
+++ b/code/game/objects/items/weapons/material/knives.dm
@@ -58,11 +58,12 @@
var/obj/S = thing
usr.visible_message(SPAN_NOTICE("[usr] starts carefully digging out something in [H == usr ? "themselves" : H]..."))
O.take_damage(8, 0, DAMAGE_FLAG_SHARP|DAMAGE_FLAG_EDGE, src)
- H.custom_pain(SPAN_DANGER("It burns!"), 50)
+ H.custom_pain(SPAN_DANGER("It burns!"), 50, affecting = O)
if(do_mob(usr, H, 100))
- H.remove_implant(S, FALSE)
+ H.remove_implant(S, FALSE, O)
log_and_message_admins("has extracted [S] out of [key_name(H)]")
- H.emote("scream")
+ if(ORGAN_CAN_FEEL_PAIN(O))
+ H.emote("scream")
/obj/item/material/knife/ritual
name = "ritual knife"
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 4181b869806..e4cd5e38288 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1125,7 +1125,7 @@
/mob/proc/embedded_needs_process()
return (embedded.len > 0)
-/mob/proc/remove_implant(obj/item/implant, surgical_removal = FALSE)
+/mob/proc/remove_implant(obj/item/implant, surgical_removal = FALSE, obj/item/organ/external/affected)
if(!LAZYLEN(get_visible_implants(0))) //Yanking out last object - removing verb.
remove_verb(src, /mob/proc/yank_out_object)
for(var/obj/item/O in pinned)
@@ -1134,7 +1134,8 @@
if(!length(pinned))
anchored = 0
implant.dropInto(loc)
- implant.add_blood(src)
+ if(!affected || !BP_IS_ROBOTIC(affected))
+ implant.add_blood(src)
implant.update_icon()
if(istype(implant,/obj/item/implant))
var/obj/item/implant/imp = implant
@@ -1157,7 +1158,7 @@
apply_damage((implant.w_class * 7), DAMAGE_BRUTE, affected)
if(!BP_IS_ROBOTIC(affected) && prob(implant.w_class * 5) && affected.sever_artery()) //I'M SO ANEMIC I COULD JUST -DIE-.
custom_pain("Something tears wetly in your [affected.name] as [implant] is pulled free!", 50, affecting = affected)
- . = ..()
+ . = ..(implant, surgical_removal, affected)
/mob/proc/yank_out_object()
set category = "Object"
diff --git a/code/modules/organs/internal/_internal.dm b/code/modules/organs/internal/_internal.dm
index 80355b4a0d4..b7d5294a54d 100644
--- a/code/modules/organs/internal/_internal.dm
+++ b/code/modules/organs/internal/_internal.dm
@@ -165,7 +165,6 @@
take_damage(owner.chem_effects[toxin_type] * seconds_per_tick)
handle_regeneration(seconds_per_tick)
- tick_surge_damage(seconds_per_tick) //Yes, this is intentional.
/obj/item/organ/internal/proc/handle_regeneration(seconds_per_tick)
SHOULD_CALL_PARENT(TRUE)
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 4648462e9bf..c9d5c75e98d 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -181,7 +181,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
if (is_immune)
germ_level = 0
- if((BP_IS_ROBOTIC(src) || robotic >= ROBOTIC_MECHANICAL) && surge_damage)
+ if(surge_damage)
tick_surge_damage(seconds_per_tick)
if(!owner)
@@ -231,6 +231,8 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
do_surge_effects()
surge_damage = max(0, surge_damage - (surge_recovery_per_second * seconds_per_tick))
+ if(!surge_damage)
+ clear_surge_effects()
return surge_damage
/obj/item/organ/proc/do_surge_effects()
@@ -294,6 +296,8 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
/obj/item/organ/proc/rejuvenate()
damage = 0
+ surge_damage = 0
+ clear_surge_effects()
/obj/item/organ/proc/heal_damage(amount)
if(can_recover())
@@ -447,9 +451,10 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
#define MAXIMUM_SURGE_DAMAGE 100
/obj/item/organ/proc/take_surge_damage(var/surge)
- if(!BP_IS_ROBOTIC(src))
+ if(!(status & ORGAN_ASSISTED))
return //We check earlier, but just to make sure.
+ START_PROCESSING(SSprocessing, src)
surge_damage = clamp(0, surge + surge_damage, MAXIMUM_SURGE_DAMAGE) //We want X seconds at most of hampered movement or what have you.
/**
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index b10a564d3ea..f30e5490c13 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -782,6 +782,8 @@ This function completely restores a damaged organ to perfect condition.
/obj/item/organ/external/proc/need_process()
if(BP_IS_ROBOTIC(src))
return surge_damage
+ if(surge_damage)
+ return TRUE
if(get_pain() || status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED|ORGAN_ARTERY_CUT) || brute_dam || burn_dam)
return TRUE
if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
@@ -813,9 +815,6 @@ This function completely restores a damaged organ to perfect condition.
if(!(status & ORGAN_BROKEN))
perma_injury = 0
- if(surge_damage && (status & ORGAN_ASSISTED))
- tick_surge_damage(seconds_per_tick) //Yes, this being here is intentional since this proc does not call ..() unless the owner is null.
-
//Infections
update_germs()
@@ -823,7 +822,6 @@ This function completely restores a damaged organ to perfect condition.
check_rigsplints()
/obj/item/organ/external/do_surge_effects()
- START_PROCESSING(SSprocessing, src)
if(prob(surge_damage))
owner.custom_pain("The artificial nerves in your [name] scream out in pain!", surge_damage/6)
diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm
index 1c377eecda3..db8bab0e9ac 100644
--- a/code/modules/organs/pain.dm
+++ b/code/modules/organs/pain.dm
@@ -7,7 +7,7 @@
// power decides how much painkillers will stop the message
// force means it ignores anti-spam timer
/mob/living/carbon/proc/custom_pain(var/message, var/power, var/force, var/obj/item/organ/external/affecting, var/nohalloss)
- if(!message || stat || !can_feel_pain() || chem_effects[CE_PAINKILLER] > power)
+ if(!message || stat || !can_feel_pain() || (affecting && !ORGAN_CAN_FEEL_PAIN(affecting)) || chem_effects[CE_PAINKILLER] > power)
return 0
power -= chem_effects[CE_PAINKILLER]/2 //Take the edge off.
diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm
index ed8a182fcfc..9b3e4162739 100644
--- a/code/modules/surgery/implant.dm
+++ b/code/modules/surgery/implant.dm
@@ -60,7 +60,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \
"You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." )
- target.custom_pain("The pain in your chest is living hell!",1)
+ target.custom_pain("The pain in your chest is living hell!", 1, affecting = affected)
affected.cavity = CAVITY_OPEN
..()
@@ -91,7 +91,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \
"You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." )
- target.custom_pain("The pain in your chest is living hell!", 75)
+ target.custom_pain("The pain in your chest is living hell!", 75, affecting = affected)
affected.cavity = CAVITY_CLOSED
..()
@@ -125,8 +125,8 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \
SPAN_NOTICE("You start putting \the [tool] inside [target]'s [get_cavity(affected)] cavity." ))
- target.custom_pain("The pain in your chest is living hell!", 75)
- playsound(target.loc, 'sound/effects/squelch1.ogg', 50, 1)
+ target.custom_pain("The pain in your chest is living hell!", 75, affecting = affected)
+ playsound(target.loc, BP_IS_ROBOTIC(affected) ? 'sound/items/wrench.ogg' : 'sound/effects/squelch1.ogg', 50, 1)
..()
/singleton/surgery_step/cavity/place_item/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -168,7 +168,7 @@
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!", 50)
+ target.custom_pain("The pain in your [affected.name] is living hell!", 50, affecting = affected)
..()
/singleton/surgery_step/cavity/implant_removal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -203,7 +203,7 @@
worm.detach()
worm.leave_host()
- playsound(target.loc, 'sound/effects/squelch1.ogg', 50, 1)
+ playsound(target.loc, BP_IS_ROBOTIC(affected) ? 'sound/items/wrench.ogg' : 'sound/effects/squelch1.ogg', 50, 1)
else
user.visible_message("[user] could not find anything inside [target]'s [affected.name], and pulls \the [tool] out.", \
SPAN_NOTICE("You could not find anything inside [target]'s [affected.name].") )
@@ -214,4 +214,3 @@
user.visible_message(SPAN_WARNING("[user] loses their grip and stabs [target] with \the [tool]!"), SPAN_WARNING("You lose your grip on \the [tool] and stab [target]!"))
affected.sever_artery()
target.apply_damage(25, DAMAGE_BRUTE, target_zone)
-
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 90a8beaa4d5..eecc31d53b2 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -142,7 +142,7 @@
user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \
SPAN_NOTICE("You start mending the damage to [target]'s [I.name]'s mechanisms." ))
- target.custom_pain("The pain in your [affected.name] is living hell!", 75)
+ target.custom_pain("The pain in your [affected.name] is living hell!", 75, affecting = affected)
..()
/singleton/surgery_step/internal/fix_organ_robotic/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -383,7 +383,7 @@
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]!", 75)
+ target.custom_pain("Someone's rooting around in your [affected.name]!", 75, affecting = affected)
..()
/singleton/surgery_step/internal/replace_organ/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 14e05665682..263f4f13ccc 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -302,7 +302,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(SPAN_DANGER("[user] is beginning to amputate [target]'s [affected.name] with \the [tool].") , \
SPAN_DANGER("You begin to cut through [target]'s [affected.amputation_point] with \the [tool]."))
- target.custom_pain("Your [affected.amputation_point] is being ripped apart!", 75)
+ target.custom_pain("Your [affected.amputation_point] is being ripped apart!", 75, affecting = affected)
..()
/singleton/surgery_step/amputate/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
diff --git a/html/changelogs/Geeves-surge_damage_fix.yml b/html/changelogs/Geeves-surge_damage_fix.yml
new file mode 100644
index 00000000000..adab8d6dc93
--- /dev/null
+++ b/html/changelogs/Geeves-surge_damage_fix.yml
@@ -0,0 +1,7 @@
+author: Geeves
+
+delete-after: True
+
+changes:
+ - bugfix: "Fixed robotic and mechanically assisted organs retaining or recovering from EMP surge damage incorrectly."
+ - bugfix: "Fixed several prosthetic limb interactions causing inappropriate pain, screams, blood, or organic surgery sounds."