From 8ff637cae968bcf65105abc8e1f9f8752d763cc5 Mon Sep 17 00:00:00 2001 From: explosivekitty Date: Fri, 26 Dec 2025 07:19:24 +0100 Subject: [PATCH] Healing cybernetic limbs automatically switches to the next limb after finishing with previous one (#4935) ## About The Pull Request You no longer have to manually target each limb when trying to repair synthetic people just like with organic people ## Why It's Good For The Game Targeting each body zone is annoying, just think about the people without number pad that have to click every body part in bottom right ## Proof Of Testing
Screenshots/Videos https://github.com/user-attachments/assets/977c1831-69ea-42f4-9adf-fe8be2152527
## Changelog :cl: qol: welding tool and cable coil will now automatically switch to damaged synthetic limbs just like sutures and regen meshes /:cl: --------- Co-authored-by: Alexis --- .../game/objects/items/tools/weldingtool.dm | 56 ++++++++++++++++++ modular_zubbers/code/modules/power/cable.dm | 57 +++++++++++++++++++ tgstation.dme | 2 + 3 files changed, 115 insertions(+) create mode 100644 modular_zubbers/code/game/objects/items/tools/weldingtool.dm create mode 100644 modular_zubbers/code/modules/power/cable.dm diff --git a/modular_zubbers/code/game/objects/items/tools/weldingtool.dm b/modular_zubbers/code/game/objects/items/tools/weldingtool.dm new file mode 100644 index 00000000000..f970fd2c131 --- /dev/null +++ b/modular_zubbers/code/game/objects/items/tools/weldingtool.dm @@ -0,0 +1,56 @@ +/obj/item/weldingtool/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if(!status && interacting_with.is_refillable()) + reagents.trans_to(interacting_with, reagents.total_volume, transferred_by = user) + to_chat(user, span_notice("You empty [src]'s fuel tank into [interacting_with].")) + update_appearance() + return ITEM_INTERACT_SUCCESS + if(!ishuman(interacting_with)) + return NONE + if(user.combat_mode) + return NONE + + return try_heal(interacting_with, user) + +/obj/item/weldingtool/proc/try_heal(atom/interacting_with, mob/living/user) + var/mob/living/carbon/carbon_patient = interacting_with + var/obj/item/bodypart/preferred_limb = carbon_patient.get_bodypart(check_zone(user.zone_selected)) + if(isnull(preferred_limb) || !IS_ROBOTIC_LIMB(preferred_limb)) + return NONE + if(!(preferred_limb.brute_dam > 0)) + balloon_alert(user, "limb not damaged") + return ITEM_INTERACT_BLOCKING + var/list/damaged_limbs = list() + for(var/obj/item/bodypart/limb as anything in carbon_patient.bodyparts) + if(isnull(limb) || !IS_ROBOTIC_LIMB(limb) || !(limb.brute_dam > 0)) + continue + damaged_limbs += limb + return try_auto_heal(interacting_with, user, damaged_limbs, preferred_limb) + +/obj/item/weldingtool/proc/try_auto_heal(atom/interacting_with, mob/living/user, list/damaged_limbs, preferred_limb) + var/mob/living/carbon/human/attacked_humanoid = interacting_with + var/obj/item/bodypart/repaired = (preferred_limb in damaged_limbs) ? preferred_limb : damaged_limbs[1] + if(!(repaired.brute_dam > 0)) + var/list/updated_damaged_limbs = damaged_limbs + updated_damaged_limbs.Remove(repaired) + if(!length(damaged_limbs)) + user.balloon_alert(user, "fully repaired") + return ITEM_INTERACT_SUCCESS + user.balloon_alert(user, "repairing [updated_damaged_limbs[1]]") + INVOKE_ASYNC(src, PROC_REF(try_auto_heal), interacting_with, user, updated_damaged_limbs, preferred_limb) + return + + user.visible_message(span_notice("[user] starts to fix some of the dents on [attacked_humanoid == user ? user.p_their() : "[attacked_humanoid]'s"] [repaired.name]."), + span_notice("You start fixing some of the dents on [attacked_humanoid == user ? "your" : "[attacked_humanoid]'s"] [repaired.name].")) + var/use_delay = 1 SECONDS + if(user == attacked_humanoid) + use_delay = 5 SECONDS + + if(!use_tool(attacked_humanoid, user, use_delay, volume=50, amount=1)) + return ITEM_INTERACT_BLOCKING + + repaired.heal_damage(brute = 15, burn = 0, required_bodytype = BODYTYPE_ROBOTIC) + user.visible_message(span_notice("[user] fixes some of the dents on [attacked_humanoid]'s [repaired.name]."), \ + span_notice("You fix some of the dents on [attacked_humanoid == user ? "your" : "[attacked_humanoid]'s"] [repaired.name].")) + + INVOKE_ASYNC(src, PROC_REF(try_auto_heal), interacting_with, user, damaged_limbs, preferred_limb) + return ITEM_INTERACT_SUCCESS diff --git a/modular_zubbers/code/modules/power/cable.dm b/modular_zubbers/code/modules/power/cable.dm new file mode 100644 index 00000000000..f7b1f757194 --- /dev/null +++ b/modular_zubbers/code/modules/power/cable.dm @@ -0,0 +1,57 @@ +/obj/item/stack/cable_coil/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if(!ishuman(interacting_with)) + return NONE + + if(user.combat_mode) + return NONE + + return try_heal(interacting_with, user) + +/obj/item/stack/cable_coil/proc/try_heal(atom/interacting_with, mob/living/user) + var/mob/living/carbon/human/carbon_patient = interacting_with + var/obj/item/bodypart/preferred_limb = carbon_patient.get_bodypart(check_zone(user.zone_selected)) + var/obj/item/clothing/under/uniform = carbon_patient.w_uniform + if(uniform?.has_sensor == BROKEN_SENSORS) + if(uniform?.repair_sensors(user)) + return ITEM_INTERACT_SUCCESS + if(isnull(preferred_limb) || !IS_ROBOTIC_LIMB(preferred_limb)) + return NONE + if(!(preferred_limb.burn_dam > 0)) + balloon_alert(user, "limb not damaged") + return ITEM_INTERACT_BLOCKING + var/list/damaged_limbs = list() + for(var/obj/item/bodypart/limb as anything in carbon_patient.bodyparts) + if(isnull(limb) || !IS_ROBOTIC_LIMB(limb) || !(limb.burn_dam > 0)) + continue + damaged_limbs += limb + return try_auto_heal(interacting_with, user, damaged_limbs, preferred_limb) + +/obj/item/stack/cable_coil/proc/try_auto_heal(atom/interacting_with, mob/living/user, list/damaged_limbs, preferred_limb) + var/mob/living/carbon/human/attacked_humanoid = interacting_with + var/obj/item/bodypart/repaired = (preferred_limb in damaged_limbs) ? preferred_limb : damaged_limbs[1] + if(!(repaired.burn_dam > 0)) + var/list/updated_damaged_limbs = damaged_limbs + updated_damaged_limbs.Remove(repaired) + if(!length(damaged_limbs)) + user.balloon_alert(user, "fully repaired") + return ITEM_INTERACT_SUCCESS + user.balloon_alert(user, "repairing [updated_damaged_limbs[1]]") + INVOKE_ASYNC(src, PROC_REF(try_auto_heal), interacting_with, user, updated_damaged_limbs, preferred_limb) + return + + user.visible_message(span_notice("[user] starts to fix some of the wires in [attacked_humanoid == user ? user.p_their() : "[attacked_humanoid]'s"] [repaired.name]."), + span_notice("You start fixing some of the wires in [attacked_humanoid == user ? "your" : "[attacked_humanoid]'s"] [repaired.name].")) + var/use_delay = 1 SECONDS + if(user == attacked_humanoid) + use_delay = 5 SECONDS + + if(!do_after(user, use_delay, attacked_humanoid)) + return ITEM_INTERACT_BLOCKING + + repaired.heal_damage(brute = 0, burn = 15, required_bodytype = BODYTYPE_ROBOTIC) + user.visible_message(span_notice("[user] fixes some of the burnt wires on [attacked_humanoid]'s [repaired.name]."), \ + span_notice("You fix some of the burnt wires on [attacked_humanoid == user ? "your" : "[attacked_humanoid]'s"] [repaired.name].")) + + if (use(1) && amount > 0) + INVOKE_ASYNC(src, PROC_REF(try_auto_heal), interacting_with, user, damaged_limbs, preferred_limb) + return ITEM_INTERACT_SUCCESS diff --git a/tgstation.dme b/tgstation.dme index ea47f93de8e..f706a895182 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9084,6 +9084,7 @@ #include "modular_zubbers\code\game\objects\items\storage\garment.dm" #include "modular_zubbers\code\game\objects\items\storage\medkit.dm" #include "modular_zubbers\code\game\objects\items\tanks\tank_types.dm" +#include "modular_zubbers\code\game\objects\items\tools\weldingtool.dm" #include "modular_zubbers\code\game\objects\structures\aliens.dm" #include "modular_zubbers\code\game\objects\structures\chalkboard.dm" #include "modular_zubbers\code\game\objects\structures\lewd_portals.dm" @@ -9622,6 +9623,7 @@ #include "modular_zubbers\code\modules\paperwork\paper_premade.dm" #include "modular_zubbers\code\modules\paperwork\stamps.dm" #include "modular_zubbers\code\modules\pen_medipens\pen_medipens.dm" +#include "modular_zubbers\code\modules\power\cable.dm" #include "modular_zubbers\code\modules\power\powerator.dm" #include "modular_zubbers\code\modules\power\singularity\emitter.dm" #include "modular_zubbers\code\modules\power\supermatter\supermatter_delam.dm"