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

🆑 Melbert
fix: Changing species no longer drops all held items
fix: Losing your right hand not un-cuffing you or dropping your gloves
/🆑
This commit is contained in:
MrMelbert
2023-02-13 13:11:54 -06:00
committed by GitHub
parent 09122e5e7a
commit 809a0b5eba
3 changed files with 40 additions and 53 deletions
+1 -1
View File
@@ -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."))
+21 -52
View File
@@ -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
@@ -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.")