From 809a0b5eba52dab07bb2fa8111f1e0beaa25f521 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Mon, 13 Feb 2023 13:11:54 -0600 Subject: [PATCH] Fixes changing species causing you to drop held items, Fixes loss of right arm not applying typical "lost arm" effects (#73356) ## About The Pull Request `drop_limb(special = TRUE)` will now no longer drop held items. This can cause issues if people are misusing `special`, but if people are not then it's fine, as it's supposed to be replaced just after. Also cut out some copy-pasta from arm and leg `drop_limb`. Since they're one unified type, they no longer needed to carry across both. This fixed another bug Also also, I was able to move the held index check out of core bodypart code, and down to arm level. This MAY have side effects, which I'm observing for. ## Why It's Good For The Game Changing species let you drop no-drop items, super lame ## Changelog :cl: Melbert fix: Changing species no longer drops all held items fix: Losing your right hand not un-cuffing you or dropping your gloves /:cl: --- code/modules/mob/living/carbon/carbon.dm | 2 +- .../surgery/bodyparts/dismemberment.dm | 73 ++++++------------- .../unit_tests/species_change_clothing.dm | 18 +++++ 3 files changed, 40 insertions(+), 53 deletions(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 1f805ac01c4..a4921afad6d 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1080,7 +1080,7 @@ switch(edit_action) if("remove") if(BP) - BP.drop_limb(special = TRUE) + BP.drop_limb() admin_ticket_log("[key_name_admin(usr)] has removed [src]'s [parse_zone(BP.body_zone)]") else to_chat(usr, span_boldwarning("[src] doesn't have such bodypart.")) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 60a2a06e514..e3024e0a074 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -93,13 +93,6 @@ update_limb(1) owner.remove_bodypart(src) - if(held_index) - if(owner.hand_bodyparts[held_index] == src) - // We only want to do this if the limb being removed is the active hand part. - // This catches situations where limbs are "hot-swapped" such as augmentations and roundstart prosthetics. - owner.dropItemToGround(owner.get_item_for_held_index(held_index), 1) - owner.hand_bodyparts[held_index] = null - for(var/datum/wound/wound as anything in wounds) wound.remove_wound(TRUE) @@ -240,44 +233,31 @@ if(special) return ..() -/obj/item/bodypart/arm/right/drop_limb(special) - . = ..() - - var/mob/living/carbon/arm_owner = owner - if(arm_owner && !special) - if(arm_owner.handcuffed) - arm_owner.handcuffed.forceMove(drop_location()) - arm_owner.handcuffed.dropped(arm_owner) - arm_owner.set_handcuffed(null) - arm_owner.update_handcuffed() - if(arm_owner.hud_used) - var/atom/movable/screen/inventory/hand/R_hand = arm_owner.hud_used.hand_slots["[held_index]"] - if(R_hand) - R_hand.update_appearance() - if(arm_owner.gloves) - arm_owner.dropItemToGround(arm_owner.gloves, TRUE) - arm_owner.update_worn_gloves() //to remove the bloody hands overlay - - -/obj/item/bodypart/arm/left/drop_limb(special) +/obj/item/bodypart/arm/drop_limb(special) var/mob/living/carbon/arm_owner = owner . = ..() - if(arm_owner && !special) - if(arm_owner.handcuffed) - arm_owner.handcuffed.forceMove(drop_location()) - arm_owner.handcuffed.dropped(arm_owner) - arm_owner.set_handcuffed(null) - arm_owner.update_handcuffed() - if(arm_owner.hud_used) - var/atom/movable/screen/inventory/hand/L_hand = arm_owner.hud_used.hand_slots["[held_index]"] - if(L_hand) - L_hand.update_appearance() - if(arm_owner.gloves) - arm_owner.dropItemToGround(arm_owner.gloves, TRUE) - arm_owner.update_worn_gloves() //to remove the bloody hands overlay + if(special || !arm_owner) + return -/obj/item/bodypart/leg/right/drop_limb(special) + if(arm_owner.hand_bodyparts[held_index] == src) + // We only want to do this if the limb being removed is the active hand part. + // This catches situations where limbs are "hot-swapped" such as augmentations and roundstart prosthetics. + arm_owner.dropItemToGround(arm_owner.get_item_for_held_index(held_index), 1) + arm_owner.hand_bodyparts[held_index] = null + if(arm_owner.handcuffed) + arm_owner.handcuffed.forceMove(drop_location()) + arm_owner.handcuffed.dropped(arm_owner) + arm_owner.set_handcuffed(null) + arm_owner.update_handcuffed() + if(arm_owner.hud_used) + var/atom/movable/screen/inventory/hand/associated_hand = arm_owner.hud_used.hand_slots["[held_index]"] + associated_hand?.update_appearance() + if(arm_owner.gloves) + arm_owner.dropItemToGround(arm_owner.gloves, TRUE) + arm_owner.update_worn_gloves() //to remove the bloody hands overlay + +/obj/item/bodypart/leg/drop_limb(special) if(owner && !special) if(owner.legcuffed) owner.legcuffed.forceMove(owner.drop_location()) //At this point bodypart is still in nullspace @@ -288,17 +268,6 @@ owner.dropItemToGround(owner.shoes, TRUE) return ..() -/obj/item/bodypart/leg/left/drop_limb(special) //copypasta - if(owner && !special) - if(owner.legcuffed) - owner.legcuffed.forceMove(owner.drop_location()) - owner.legcuffed.dropped(owner) - owner.legcuffed = null - owner.update_worn_legcuffs() - if(owner.shoes) - owner.dropItemToGround(owner.shoes, TRUE) - return ..() - /obj/item/bodypart/head/drop_limb(special) if(!special) //Drop all worn head items diff --git a/code/modules/unit_tests/species_change_clothing.dm b/code/modules/unit_tests/species_change_clothing.dm index cad10f216a6..c6803709960 100644 --- a/code/modules/unit_tests/species_change_clothing.dm +++ b/code/modules/unit_tests/species_change_clothing.dm @@ -27,3 +27,21 @@ var/obj/item/human_collar = morphing_human.get_item_by_slot(ITEM_SLOT_NECK) TEST_ASSERT_NOTEQUAL(equipped_collar, human_collar, "Human still has a Monkey collar after changing species.") + +///Gives a Human items in both hands, then swaps them to be another species. Held items should remain. +/datum/unit_test/species_change_held_items + +/datum/unit_test/species_change_held_items/Run() + var/mob/living/carbon/human/morphing_human = allocate(/mob/living/carbon/human/dummy/consistent) + var/obj/item/item_a = allocate(/obj/item/storage/toolbox) + var/obj/item/item_b = allocate(/obj/item/melee/baton/security/loaded) + morphing_human.put_in_hands(item_a) + morphing_human.put_in_hands(item_b) + + var/pre_change_num = length(morphing_human.get_empty_held_indexes()) + TEST_ASSERT_EQUAL(pre_change_num, 0, "Human had empty hands before the species change happened.") + + morphing_human.set_species(/datum/species/lizard) + + var/post_change_num = length(morphing_human.get_empty_held_indexes()) + TEST_ASSERT_EQUAL(post_change_num, 0, "Human had empty hands after the species change happened, but they should've kept their items.")