diff --git a/code/__HELPERS/atoms.dm b/code/__HELPERS/atoms.dm index c2b3b89de2d64..b55555d052621 100644 --- a/code/__HELPERS/atoms.dm +++ b/code/__HELPERS/atoms.dm @@ -350,3 +350,18 @@ B --><-- A return get_step(ref, base_dir) */ + +/// returns a mob that possesses this atom(usually item), +/// or returns null if it is possessed by no mob. +/atom/proc/get_mob_loc(as_first_mob=TRUE) + var/atom/upper = src + var/final_mob + while(upper) + upper = upper.loc + if(ismob(upper)) + final_mob = upper + // if this is TRUE, it will immediately return a mob that holds the atom + // if this is FALSE, it will find a final mob when it's chain-contained (i.e. mob in mob in mob...) + if(as_first_mob) + return final_mob + return final_mob diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index e1123759e9a30..90ad887cbf746 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -309,14 +309,7 @@ /datum/action/item_action/chameleon/change/proc/update_mob_hud(atom/card_holder) // we're going to find a human, and store human ref to 'card_holder' by checking loc multiple time. if(!ishuman(card_holder)) - if(!card_holder) - card_holder = target.loc - if(istype(card_holder, /obj/item/storage/wallet)) - card_holder = card_holder.loc // this should be human - if(istype(card_holder, /obj/item/computer_hardware/card_slot)) - card_holder = card_holder.loc - if(istype(card_holder, /obj/item/modular_computer/tablet)) - card_holder = card_holder.loc // tihs should be human + card_holder = target.get_mob_loc() if(!ishuman(card_holder)) return var/mob/living/carbon/human/card_holding_human = card_holder diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 65ef7c2305fdf..08c3fa83708d4 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -161,7 +161,7 @@ /mob/proc/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE) return FALSE -/mob/proc/can_put_in_hand(I, hand_index) +/mob/proc/can_put_in_hand(atom/I, hand_index) if(hand_index > length(held_items)) return FALSE if(!put_in_hand_check(I)) @@ -209,7 +209,12 @@ return FALSE //Puts the item into our active hand if possible. returns TRUE on success. -/mob/proc/put_in_active_hand(obj/item/I, forced = FALSE, ignore_animation = TRUE) +/mob/proc/put_in_active_hand(obj/item/I, forced = FALSE, ignore_animation = TRUE, checks_mob_loc=TRUE) + if(checks_mob_loc) // checks if it's possessed by a mob to prevent client delay. offer code sends this as FALSE. + var/owner = I.get_mob_loc() + if(ismob(owner) && owner != src) + show_message("You wanted to pick up [src], but it's already on someone's hand. You feel bad about the space latency...") + return FALSE // sorry, you won't get the benefit of your bad latency. return put_in_hand(I, active_hand_index, forced, ignore_animation) @@ -221,7 +226,7 @@ //Puts the item our active hand if possible. Failing that it tries other hands. Returns TRUE on success. //If both fail it drops it on the floor and returns FALSE. //This is probably the main one you need to know :) -/mob/proc/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, forced = FALSE) +/mob/proc/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, forced = FALSE, checks_mob_loc = TRUE) if(QDELETED(I)) return FALSE @@ -245,7 +250,7 @@ to_chat(usr, "Your [inactive_stack.name] stack now contains [inactive_stack.get_amount()] [inactive_stack.singular_name]\s.") return TRUE - if(put_in_active_hand(I, forced)) + if(put_in_active_hand(I, forced, checks_mob_loc=checks_mob_loc)) return TRUE var/hand = get_empty_held_index_for_side("l") diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index abe3f9c158ba5..85d86fa5da16c 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -355,4 +355,4 @@ return visible_message("[src] takes [I] from [offerer]", \ "You take [I] from [offerer]") - put_in_hands(I) + put_in_hands(I, checks_mob_loc=FALSE)