diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index 4e3f5a4cf28..c98168560b7 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -22,9 +22,11 @@ // /mob/living/carbon physiology signals #define COMSIG_CARBON_GAIN_WOUND "carbon_gain_wound" //from /datum/wound/proc/apply_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L) #define COMSIG_CARBON_LOSE_WOUND "carbon_lose_wound" //from /datum/wound/proc/remove_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L) -///from base of /obj/item/bodypart/proc/attach_limb(): (new_limb, special) allows you to fail limb attachment -#define COMSIG_CARBON_ATTACH_LIMB "carbon_attach_limb" +///from base of /obj/item/bodypart/proc/can_attach_limb(): (new_limb, special) allows you to fail limb attachment +#define COMSIG_ATTEMPT_CARBON_ATTACH_LIMB "attempt_carbon_attach_limb" #define COMPONENT_NO_ATTACH (1<<0) +///from base of /obj/item/bodypart/proc/try_attach_limb(): (new_limb, special) +#define COMSIG_CARBON_ATTACH_LIMB "carbon_attach_limb" #define COMSIG_BODYPART_GAUZED "bodypart_gauzed" // from /obj/item/bodypart/proc/apply_gauze(/obj/item/stack/gauze) #define COMSIG_BODYPART_GAUZE_DESTROYED "bodypart_degauzed" // from [/obj/item/bodypart/proc/seep_gauze] when it runs out of absorption diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index dfab1c57977..5ca662cfec1 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -518,7 +518,7 @@ head.drop_organs() qdel(head) owner.regenerate_icons() - RegisterSignal(owner, COMSIG_CARBON_ATTACH_LIMB, .proc/abortattachment) + RegisterSignal(owner, COMSIG_ATTEMPT_CARBON_ATTACH_LIMB, .proc/abortattachment) /datum/mutation/human/headless/on_losing() . = ..() @@ -527,7 +527,7 @@ var/obj/item/organ/internal/brain/brain = owner.getorganslot(ORGAN_SLOT_BRAIN) if(brain) //so this doesn't instantly kill you. we could delete the brain, but it lets people cure brain issues they /really/ shouldn't be brain.zone = BODY_ZONE_HEAD - UnregisterSignal(owner, COMSIG_CARBON_ATTACH_LIMB) + UnregisterSignal(owner, COMSIG_ATTEMPT_CARBON_ATTACH_LIMB) var/successful = owner.regenerate_limb(BODY_ZONE_HEAD) if(!successful) stack_trace("HARS mutation head regeneration failed! (usually caused by headless syndrome having a head)") diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 301b239be09..6a32f5b34a2 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -237,7 +237,7 @@ //If user does not have the corresponding hand anymore, give them one and return the rod to their hand if(((hand % 2) == 0)) var/obj/item/bodypart/L = itemUser.newBodyPart(BODY_ZONE_R_ARM, FALSE, FALSE) - if(L.attach_limb(itemUser)) + if(L.try_attach_limb(itemUser)) itemUser.put_in_hand(newRod, hand, forced = TRUE) else qdel(L) @@ -245,7 +245,7 @@ return else var/obj/item/bodypart/L = itemUser.newBodyPart(BODY_ZONE_L_ARM, FALSE, FALSE) - if(L.attach_limb(itemUser)) + if(L.try_attach_limb(itemUser)) itemUser.put_in_hand(newRod, hand, forced = TRUE) else qdel(L) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 8e1ccc82b39..82bd0b58a5f 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -485,7 +485,7 @@ var/obj/item/bodypart/BP = new path () BP.held_index = i - BP.attach_limb(src, TRUE) + BP.try_attach_limb(src, TRUE) hand_bodyparts[i] = BP ..() //Don't redraw hands until we have organs for them diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 8bf993f65fd..449aba7b4fc 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -966,7 +966,7 @@ hand_bodyparts += bodypart_instance -///Proc to hook behavior on bodypart additions. Do not directly call. You're looking for [/obj/item/bodypart/proc/attach_limb()]. +///Proc to hook behavior on bodypart additions. Do not directly call. You're looking for [/obj/item/bodypart/proc/try_attach_limb()]. /mob/living/carbon/proc/add_bodypart(obj/item/bodypart/new_bodypart) SHOULD_NOT_OVERRIDE(TRUE) diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index c93c10ee8ce..f734c27e7a1 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -277,7 +277,7 @@ if(HAS_TRAIT(victim, TRAIT_LIMBATTACHMENT)) if(!human_victim.get_bodypart(body_zone)) user.temporarilyRemoveItemFromInventory(src, TRUE) - if(!attach_limb(victim)) + if(!try_attach_limb(victim)) to_chat(user, span_warning("[human_victim]'s body rejects [src]!")) forceMove(human_victim.loc) if(human_victim == user) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 9ddb7ee2ab7..4793a9aaee9 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -322,19 +322,26 @@ if(old_limb) old_limb.drop_limb(TRUE) - . = attach_limb(limb_owner, special) + . = try_attach_limb(limb_owner, special) if(!.) //If it failed to replace, re-attach their old limb as if nothing happened. - old_limb.attach_limb(limb_owner, TRUE) + old_limb.try_attach_limb(limb_owner, TRUE) -///Attach src to target mob if able. -/obj/item/bodypart/proc/attach_limb(mob/living/carbon/new_limb_owner, special) - if(SEND_SIGNAL(new_limb_owner, COMSIG_CARBON_ATTACH_LIMB, src, special) & COMPONENT_NO_ATTACH) +///Checks if you can attach a limb, returns TRUE if you can. +/obj/item/bodypart/proc/can_attach_limb(mob/living/carbon/new_limb_owner, special) + if(SEND_SIGNAL(new_limb_owner, COMSIG_ATTEMPT_CARBON_ATTACH_LIMB, src, special) & COMPONENT_NO_ATTACH) return FALSE var/obj/item/bodypart/chest/mob_chest = new_limb_owner.get_bodypart(BODY_ZONE_CHEST) if(mob_chest && !(mob_chest.acceptable_bodytype & bodytype) && !special) return FALSE + return TRUE +///Attach src to target mob if able, returns FALSE if it fails to. +/obj/item/bodypart/proc/try_attach_limb(mob/living/carbon/new_limb_owner, special) + if(!can_attach_limb(new_limb_owner, special)) + return FALSE + + SEND_SIGNAL(new_limb_owner, COMSIG_CARBON_ATTACH_LIMB, src, special) moveToNullspace() set_owner(new_limb_owner) new_limb_owner.add_bodypart(src) @@ -386,7 +393,7 @@ new_limb_owner.update_damage_overlays() return TRUE -/obj/item/bodypart/head/attach_limb(mob/living/carbon/new_head_owner, special = FALSE, abort = FALSE) +/obj/item/bodypart/head/try_attach_limb(mob/living/carbon/new_head_owner, special = FALSE, abort = FALSE) // These are stored before calling super. This is so that if the head is from a different body, it persists its appearance. var/real_name = src.real_name @@ -473,7 +480,7 @@ return FALSE limb = newBodyPart(limb_zone, 0, 0) if(limb) - if(!limb.attach_limb(src, 1)) + if(!limb.try_attach_limb(src, TRUE)) qdel(limb) return FALSE limb.update_limb(is_creating = TRUE) diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index ca9ca0fae44..05017e6372f 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -16,7 +16,7 @@ var/obj/item/bodypart/old_limb = get_bodypart(new_limb.body_zone) if(old_limb) qdel(old_limb) - new_limb.attach_limb(src, special = special) + new_limb.try_attach_limb(src, special = special) /mob/living/carbon/has_hand_for_held_index(i) if(!i) diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm index 83099d25c8b..db185acb602 100644 --- a/code/modules/surgery/prosthetic_replacement.dm +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -53,6 +53,10 @@ if(human_target.dna.species.id != bodypart_to_attach.limb_id) organ_rejection_dam = 30 + if(!bodypart_to_attach.can_attach_limb(target)) + target.balloon_alert(user, "that doesn't go on the [parse_zone(target_zone)]!") + return SURGERY_STEP_FAIL + if(target_zone == bodypart_to_attach.body_zone) //so we can't replace a leg with an arm, or a human arm with a monkey arm. display_results(user, target, span_notice("You begin to replace [target]'s [parse_zone(target_zone)] with [tool]..."), span_notice("[user] begins to replace [target]'s [parse_zone(target_zone)] with [tool]."), @@ -77,11 +81,7 @@ tool = tool.contents[1] if(isbodypart(tool) && user.temporarilyRemoveItemFromInventory(tool)) var/obj/item/bodypart/limb_to_attach = tool - if(!limb_to_attach.attach_limb(target)) - display_results(user, target, span_warning("You fail in replacing [target]'s [parse_zone(target_zone)]! Their body has rejected [limb_to_attach]!"), - span_warning("[user] fails to replace [target]'s [parse_zone(target_zone)]!"), - span_warning("[user] fails to replaces [target]'s [parse_zone(target_zone)]!")) - return + limb_to_attach.try_attach_limb(target) if(organ_rejection_dam) target.adjustToxLoss(organ_rejection_dam) display_results(user, target, span_notice("You succeed in replacing [target]'s [parse_zone(target_zone)]."), @@ -92,12 +92,7 @@ else var/obj/item/bodypart/limb_to_attach = target.newBodyPart(target_zone, FALSE, FALSE) limb_to_attach.is_pseudopart = TRUE - if(!limb_to_attach.attach_limb(target)) - display_results(user, target, span_warning("You fail in attaching [target]'s [parse_zone(target_zone)]! Their body has rejected [limb_to_attach]!"), - span_warning("[user] fails to attach [target]'s [parse_zone(target_zone)]!"), - span_warning("[user] fails to attach [target]'s [parse_zone(target_zone)]!")) - limb_to_attach.forceMove(target.loc) - return + limb_to_attach.try_attach_limb(target) user.visible_message(span_notice("[user] finishes attaching [tool]!"), span_notice("You attach [tool].")) display_results(user, target, span_notice("You attach [tool]."), span_notice("[user] finishes attaching [tool]!"),