mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
[MIRROR] Fix some shenanigans involving interaction order with wound tending [MDB IGNORE] (#25551)
* Fix some shenanigans involving interaction order with wound tending (#80225) ## About The Pull Request Fixes #80223 . See issue for information about the bug. This PR fixes it by placing wound tending before parent call but after surgery. It also fixes it by rewriting a little bit of medical stack item code to only block interaction chain when actually healing someone - This is not necessary with the above fix, but it futureproofs things. ## Changelog 🆑 Melbert fix: When using an item on a mob, you will always attempt to fix wounds AFTER surgery, BUT BEFORE the item's own interactions. As an example, this means using a mesh on a mob will attempt to progress surgery first, then attempt to fix any burn wounds, then heal burn damage. /🆑 * Fix some shenanigans involving interaction order with wound tending --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
This commit is contained in:
@@ -164,6 +164,16 @@
|
||||
return attacking_item.attack_atom(src, user, params)
|
||||
|
||||
/mob/living/item_interaction(mob/living/user, obj/item/tool, list/modifiers, is_right_clicking)
|
||||
// Surgery and such happens very high up in the interaction chain, before parent call
|
||||
var/attempt_tending = item_tending(user, tool, modifiers)
|
||||
if(attempt_tending & ITEM_INTERACT_ANY_BLOCKER)
|
||||
return attempt_tending
|
||||
|
||||
return ..() | attempt_tending
|
||||
|
||||
/// Handles any use of using a surgical tool or item on a mob to tend to them.
|
||||
/// The sole reason this is a separate proc is so carbons can tend wounds AFTER the check for surgery.
|
||||
/mob/living/proc/item_tending(mob/living/user, obj/item/tool, list/modifiers)
|
||||
for(var/datum/surgery/operation as anything in surgeries)
|
||||
if(IS_IN_INVALID_SURGICAL_POSITION(src, operation))
|
||||
continue
|
||||
@@ -172,7 +182,7 @@
|
||||
if(operation.next_step(user, modifiers))
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
return ..()
|
||||
return NONE
|
||||
|
||||
/mob/living/attackby(obj/item/attacking_item, mob/living/user, params)
|
||||
if(..())
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
/obj/item/stack/medical/interact_with_atom(atom/interacting_with, mob/living/user)
|
||||
if(!isliving(interacting_with))
|
||||
return NONE
|
||||
|
||||
try_heal(interacting_with, user)
|
||||
if(!begin_heal_loop(interacting_with, user))
|
||||
return NONE // [ITEM_INTERACT_BLOCKING] would be redundant as we are nobludgeon
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/item/stack/medical/apply_fantasy_bonuses(bonus)
|
||||
@@ -61,27 +61,57 @@
|
||||
flesh_regeneration = reset_fantasy_variable("flesh_regeneration", flesh_regeneration)
|
||||
return ..()
|
||||
|
||||
/// Used to begin the recursive healing loop.
|
||||
/// Returns TRUE if we entered the loop, FALSE if we didn't
|
||||
/obj/item/stack/medical/proc/begin_heal_loop(mob/living/patient, mob/user)
|
||||
if(!can_heal(patient, user))
|
||||
return FALSE
|
||||
|
||||
INVOKE_ASYNC(src, PROC_REF(try_heal), patient, user)
|
||||
return TRUE
|
||||
|
||||
/// Checks if the passed patient can be healed by the passed user
|
||||
/obj/item/stack/medical/proc/can_heal(mob/living/patient, mob/user)
|
||||
return patient.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE)
|
||||
|
||||
/// In which we print the message that we're starting to heal someone, then we try healing them. Does the do_after whether or not it can actually succeed on a targeted mob
|
||||
/obj/item/stack/medical/proc/try_heal(mob/living/patient, mob/user, silent = FALSE)
|
||||
if(!patient.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE))
|
||||
return
|
||||
if(patient == user)
|
||||
if(!silent)
|
||||
user.visible_message(span_notice("[user] starts to apply [src] on [user.p_them()]self..."), span_notice("You begin applying [src] on yourself..."))
|
||||
if(!do_after(user, self_delay, patient, extra_checks=CALLBACK(patient, TYPE_PROC_REF(/mob/living, try_inject), user, null, INJECT_TRY_SHOW_ERROR_MESSAGE)))
|
||||
return
|
||||
else if(other_delay)
|
||||
if(!silent)
|
||||
user.visible_message(span_notice("[user] starts to apply [src] on [patient]."), span_notice("You begin applying [src] on [patient]..."))
|
||||
if(!do_after(user, other_delay, patient, extra_checks=CALLBACK(patient, TYPE_PROC_REF(/mob/living, try_inject), user, null, INJECT_TRY_SHOW_ERROR_MESSAGE)))
|
||||
user.visible_message(
|
||||
span_notice("[user] starts to apply [src] on [user.p_them()]self..."),
|
||||
span_notice("You begin applying [src] on yourself..."),
|
||||
)
|
||||
if(!do_after(
|
||||
user,
|
||||
self_delay,
|
||||
patient,
|
||||
extra_checks = CALLBACK(src, PROC_REF(can_heal), patient, user),
|
||||
))
|
||||
return
|
||||
|
||||
if(heal(patient, user))
|
||||
log_combat(user, patient, "healed", src.name)
|
||||
use(1)
|
||||
if(repeating && amount > 0)
|
||||
try_heal(patient, user, TRUE)
|
||||
else if(other_delay)
|
||||
if(!silent)
|
||||
user.visible_message(
|
||||
span_notice("[user] starts to apply [src] on [patient]."),
|
||||
span_notice("You begin applying [src] on [patient]..."),
|
||||
)
|
||||
if(!do_after(
|
||||
user,
|
||||
other_delay,
|
||||
patient,
|
||||
extra_checks = CALLBACK(src, PROC_REF(can_heal), patient, user),
|
||||
))
|
||||
return
|
||||
|
||||
if(!heal(patient, user))
|
||||
return
|
||||
log_combat(user, patient, "healed", name)
|
||||
if(!use(1) || !repeating || amount <= 0)
|
||||
return
|
||||
if(!can_heal(patient, user))
|
||||
return
|
||||
try_heal(patient, user, silent = TRUE)
|
||||
|
||||
/// Apply the actual effects of the healing if it's a simple animal, goes to [/obj/item/stack/medical/proc/heal_carbon] if it's a carbon, returns TRUE if it works, FALSE if it doesn't
|
||||
/obj/item/stack/medical/proc/heal(mob/living/patient, mob/user)
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
var/mob/living/carbon/human/attacked_humanoid = interacting_with
|
||||
var/obj/item/bodypart/affecting = attacked_humanoid.get_bodypart(check_zone(user.zone_selected))
|
||||
if(isnull(affecting) || !IS_ROBOTIC_LIMB(affecting))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
return NONE
|
||||
|
||||
if(!use_tool(attacked_humanoid, user, 0, volume=50, amount=1))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
@@ -28,14 +28,9 @@
|
||||
QDEL_NULL(dna)
|
||||
GLOB.carbon_list -= src
|
||||
|
||||
/mob/living/carbon/item_interaction(mob/living/user, obj/item/tool, list/modifiers, is_right_clicking)
|
||||
/mob/living/carbon/item_tending(mob/living/user, obj/item/tool, list/modifiers)
|
||||
. = ..()
|
||||
if(. & ITEM_INTERACT_SUCCESS)
|
||||
return .
|
||||
|
||||
if(!length(all_wounds))
|
||||
return .
|
||||
if(user.combat_mode && user != src)
|
||||
if(. & ITEM_INTERACT_ANY_BLOCKER)
|
||||
return .
|
||||
|
||||
for(var/datum/wound/wound as anything in shuffle(all_wounds))
|
||||
|
||||
Reference in New Issue
Block a user