mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 20:45:28 +01:00
Prosthetic surgery now checks if you can attach the bodypart (#70157)
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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)")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]!"),
|
||||
|
||||
Reference in New Issue
Block a user