diff --git a/code/__DEFINES/~~bubber_defines/traits/declarations.dm b/code/__DEFINES/~~bubber_defines/traits/declarations.dm index 594783f8609..36cda32d942 100644 --- a/code/__DEFINES/~~bubber_defines/traits/declarations.dm +++ b/code/__DEFINES/~~bubber_defines/traits/declarations.dm @@ -61,3 +61,6 @@ // For Bloodsuckers/Hemophages that vomit blood #define TRAIT_STOMACH_BLOOD_VOMIT "stomach_blood_vomit" + +/// The trait that determines if someone has the robotic limb reattachment quirk. +#define TRAIT_ROBOTIC_LIMBATTACHMENT "trait_robotic_limbattachment" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index c761d27c881..eacc5d89589 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -901,6 +901,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_REVIVES_BY_HEALING" = TRAIT_REVIVES_BY_HEALING, "TRAIT_RIGGER" = TRAIT_RIGGER, "TRAIT_ROBOTIC_DNA_ORGANS" = TRAIT_ROBOTIC_DNA_ORGANS, + "TRAIT_ROBOTIC_LIMBATTACHMENT" = TRAIT_ROBOTIC_LIMBATTACHMENT, //BUBBER addition for robotic limb reattachment quirk. "TRAIT_ROPEBUNNY" = TRAIT_ROPEBUNNY, "TRAIT_RSD_COMPATIBLE" = TRAIT_RSD_COMPATIBLE, "TRAIT_SACRIFICED" = TRAIT_SACRIFICED , diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index b890cbcb217..56fe4c74110 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -478,6 +478,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_REVIVES_BY_HEALING" = TRAIT_REVIVES_BY_HEALING, "TRAIT_RIGGER" = TRAIT_RIGGER, "TRAIT_ROBOTIC_DNA_ORGANS" = TRAIT_ROBOTIC_DNA_ORGANS, + "TRAIT_ROBOTIC_LIMBATTACHMENT" = TRAIT_ROBOTIC_LIMBATTACHMENT, //BUBBER ADDITION - Trait that lets you install robotic limbs only. "TRAIT_ROPEBUNNY" = TRAIT_ROPEBUNNY, "TRAIT_RSD_COMPATIBLE" = TRAIT_RSD_COMPATIBLE, "TRAIT_SACRIFICED" = TRAIT_SACRIFICED , diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index d117311a731..50c8faf870d 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -1039,7 +1039,7 @@ GLOBAL_LIST_EMPTY(features_by_species) to_chat(owner, span_warning("You attempt to touch [target]!")) return - SEND_SIGNAL(owner, COMSIG_MOB_ATTACK_HAND, owner, target, attacker_style) + SEND_SIGNAL(owner, COMSIG_MOB_ATTACK_HAND, owner, target, attacker_style, modifiers) //BUBBER EDIT - Original line SEND_SIGNAL(owner, COMSIG_MOB_ATTACK_HAND, owner, target, attacker_style) if(LAZYACCESS(modifiers, RIGHT_CLICK)) disarm(owner, target, attacker_style) diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index bf41921041c..2457963025b 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -423,7 +423,11 @@ if(ishuman(victim)) var/mob/living/carbon/human/human_victim = victim - if(HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT) || HAS_TRAIT(src, TRAIT_EASY_ATTACH)) + if(HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT) || HAS_TRAIT(src, TRAIT_EASY_ATTACH) || (HAS_TRAIT(victim, TRAIT_ROBOTIC_LIMBATTACHMENT) && bodytype & BODYTYPE_ROBOTIC)) // BUBBER EDIT CHANGE - ORIGINAL: if(HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT) || HAS_TRAIT(src, TRAIT_EASY_ATTACH)) + // BUBBER EDIT ADDITION START - robot_limb_detach_quirk + if (!HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT) && !HAS_TRAIT(victim, TRAIT_EASY_ATTACH) && !(bodytype & BODYTYPE_ROBOTIC) && !(bodytype & BODYTYPE_KINETIC) && !(bodytype & BODYTYPE_PEG)) //if we're trying to attach something that's not synthetic, end out + return + // BUBBER EDIT ADDITION END if(!human_victim.get_bodypart(body_zone)) user.temporarilyRemoveItemFromInventory(src, TRUE) if(!try_attach_limb(victim)) diff --git a/modular_zubbers/code/modules/quirks/positive_quirks/robot_limb_detach.dm b/modular_zubbers/code/modules/quirks/positive_quirks/robot_limb_detach.dm new file mode 100644 index 00000000000..56dc1e87b9d --- /dev/null +++ b/modular_zubbers/code/modules/quirks/positive_quirks/robot_limb_detach.dm @@ -0,0 +1,94 @@ +/datum/quirk/robot_limb_detach + name = "Cybernetic Limb Mounts" + desc = "You are able to detach and reattach any installed robotic limbs with very little effort, as long as they're in good condition. Right Click yourself while targeting a limb to remove it." + gain_text = span_notice("Internal sensors report limb disengagement protocols are ready and waiting.") + lose_text = span_notice("ERROR: LIMB DISENGAGEMENT PROTOCOLS OFFLINE.") + medical_record_text = "Patient bears quick-attach and release limb joint cybernetics." + value = 4 + mob_trait = TRAIT_ROBOTIC_LIMBATTACHMENT + icon = FA_ICON_HANDSHAKE_SIMPLE_SLASH + quirk_flags = QUIRK_HUMAN_ONLY + +/datum/quirk/robot_limb_detach/add(client/client_source) + quirk_holder.AddElement(/datum/element/robot_self_amputation) + +/datum/quirk/robot_limb_detach/remove() + quirk_holder.RemoveElement(/datum/element/robot_self_amputation) + +/// Give to a human to allow them to self amputate their mechanical limbs +/datum/element/robot_self_amputation + +/datum/element/robot_self_amputation/Attach(datum/target) + . = ..() + + if(!iscarbon(target)) + return ELEMENT_INCOMPATIBLE + + RegisterSignal(target, COMSIG_MOB_ATTACK_HAND, PROC_REF(pre_self_amputate)) + + +/datum/element/robot_self_amputation/Detach(datum/source, ...) + UnregisterSignal(source, COMSIG_MOB_ATTACK_HAND) + . = ..() + +/datum/element/robot_self_amputation/proc/pre_self_amputate(mob/living/carbon/amputee, mob/amputee_again, mob/living/target, datum/martial_art/attacker_style, modifiers) + SIGNAL_HANDLER + + if(target != amputee) + return + + if(!LAZYACCESS(modifiers, RIGHT_CLICK)) + return + + var/obj/item/bodypart/targeted_limb = amputee.get_bodypart(check_zone(amputee.zone_selected)) + + if(!targeted_limb) + return + + // Chest removal Fail + if (targeted_limb.body_zone == BODY_ZONE_CHEST) + return + + // Head removal fail for people who can't live without one + if (targeted_limb.body_zone == BODY_ZONE_HEAD && !issynthetic(amputee)) + return + + // Organic Limb Fail + if (IS_ORGANIC_LIMB(targeted_limb)) + return + + if(HAS_TRAIT(amputee, TRAIT_NODISMEMBER)) + to_chat(amputee, span_warning("ERROR: LIMB DISENGAGEMENT PROTOCOLS OFFLINE. Seek out a maintenance technician.")) + return + + if (amputee.handcuffed) + to_chat(amputee, span_alert("You can't get a good enough grip with your hands bound.")) + return + + if (length(targeted_limb.wounds) >= 1) + amputee.balloon_alert(amputee, "can't detach wounded limbs!") + playsound(amputee, 'sound/machines/buzz/buzz-sigh.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + return + + INVOKE_ASYNC(src, PROC_REF(self_amputate), amputee, targeted_limb) + +/datum/element/robot_self_amputation/proc/self_amputate(mob/living/carbon/amputee, obj/item/bodypart/targeted_limb) + amputee.balloon_alert(amputee, "detaching limb...") + playsound(amputee, 'sound/items/tools/rped.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + amputee.visible_message(span_notice("[amputee] shuffles [amputee.p_their()] [targeted_limb.name] forward, actuators hissing and whirring as [amputee.p_they()] disengage[amputee.p_s()] the limb from its mount...")) + + if(!do_after(amputee, 10 SECONDS)) + amputee.balloon_alert(amputee, "interrupted!") + return + if(amputee.handcuffed) //Prevents removing your arms if you get handcuffed part way through + return + + playsound(amputee, 'sound/machines/buzz/buzz-sigh.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + amputee.visible_message(span_notice("With a gentle twist, [amputee] finally prises [amputee.p_their()] [targeted_limb.name] free from its socket.")) + targeted_limb.drop_limb() + amputee.put_in_hands(targeted_limb) + amputee.balloon_alert(amputee, "limb detached!") + if(prob(5)) + playsound(amputee, 'sound/items/champagne_pop.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + else + playsound(amputee, 'sound/items/deconstruct.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) diff --git a/tgstation.dme b/tgstation.dme index 8ad108610df..db88569d435 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9699,6 +9699,7 @@ #include "modular_zubbers\code\modules\public_logging\public_logging.dm" #include "modular_zubbers\code\modules\quirks\neutral_quirks\body_temp.dm" #include "modular_zubbers\code\modules\quirks\neutral_quirks\unique_blood_color.dm" +#include "modular_zubbers\code\modules\quirks\positive_quirks\robot_limb_detach.dm" #include "modular_zubbers\code\modules\quirks\positive_quirks\telepathy.dm" #include "modular_zubbers\code\modules\quote_of_the_round\config.dm" #include "modular_zubbers\code\modules\quote_of_the_round\debug_verbs.dm"