From 012e1f10102d3eaee8cdbc273f9775de61c1cb85 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Sat, 21 Dec 2024 16:36:04 -0500 Subject: [PATCH] Fixes for inserting/removing storage items/swapping items between hands. (#27694) * Fixes for inserting/removing storage items/swapping items between hands. * Apply suggestions from code review Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: warriorstar-orion * Fix doc comments * kill old comment --------- Signed-off-by: warriorstar-orion Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> --- code/game/objects/items.dm | 17 +++---- .../items/weapons/storage/storage_base.dm | 50 +++++++++---------- code/modules/mob/inventory_procs.dm | 50 +++++++++++++++++-- .../carbon/alien/larva/larva_inventory.dm | 2 +- .../modules/mob/living/carbon/carbon_procs.dm | 2 +- .../living/carbon/human/human_inventory.dm | 2 +- .../living/silicon/robot/robot_inventory.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 2 +- .../living/simple_animal/slime/slime_mob.dm | 2 +- 9 files changed, 83 insertions(+), 46 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 8624e047d9f..a14842fe341 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -338,26 +338,25 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons if(affecting && affecting.receive_damage(0, 5)) // 5 burn damage H.UpdateDamageIcon() - if(isstorage(src.loc)) - /// If the item is in a storage item, take it out - var/obj/item/storage/S = src.loc - S.remove_from_storage(src) - if(..()) return if(throwing) throwing.finalize(FALSE) if(loc == user) - if(HAS_TRAIT(user, TRAIT_I_WANT_BRAINS) || !user.unEquip(src, silent = TRUE)) + if(HAS_TRAIT(user, TRAIT_I_WANT_BRAINS)) + return FALSE + if(!user.canUnEquip(src, force = FALSE)) return FALSE if(flags & ABSTRACT) return FALSE - else - if(isliving(loc)) - return FALSE + if(user.is_in_inactive_hand(src)) + return user.swap_item_between_hands() + + if(isliving(loc)) + return FALSE pickup(user) add_fingerprint(user) diff --git a/code/game/objects/items/weapons/storage/storage_base.dm b/code/game/objects/items/weapons/storage/storage_base.dm index 0b5236d0e31..4f751de8025 100644 --- a/code/game/objects/items/weapons/storage/storage_base.dm +++ b/code/game/objects/items/weapons/storage/storage_base.dm @@ -436,38 +436,42 @@ * * prevent_warning - Stop the insertion message being displayed. Intended for cases when you are inserting multiple items at once. */ /obj/item/storage/proc/handle_item_insertion(obj/item/I, mob/user, prevent_warning = FALSE) - if(!istype(I)) - return FALSE - if(user) - if(!Adjacent(user) && !isnewplayer(user)) - return FALSE - if(!user.unEquip(I, silent = TRUE)) - return FALSE - user.update_icons() //update our overlays - if(QDELING(I)) + if(!istype(I) || QDELING(I)) return FALSE if(silent || HAS_TRAIT(I, TRAIT_SILENT_INSERTION)) prevent_warning = TRUE - I.forceMove(src) - if(QDELING(I)) - return FALSE - I.on_enter_storage(src) - - for(var/_M in mobs_viewing) - var/mob/M = _M - if((M.s_active == src) && M.client) - M.client.screen += I if(user) + if(!Adjacent(user) && !isnewplayer(user)) + return FALSE + if(!user.unEquip(I, force = FALSE, silent = TRUE, destination = src)) + return FALSE if(user.client && user.s_active != src) user.client.screen -= I if(length(user.observers)) for(var/mob/observer in user.observers) if(observer.client && observer.s_active != src) observer.client.screen -= I - I.dropped(user, TRUE) - if(user) + add_fingerprint(user) + user.update_icons() + + orient2hud(user) + if(user.s_active) + user.s_active.show_to(user) + else + I.forceMove(src) + + I.on_enter_storage(src) + // So you can click on the area around the item to equip it, instead of having to pixel hunt + I.mouse_opacity = MOUSE_OPACITY_OPAQUE + I.in_inventory = TRUE + + for(var/_M in mobs_viewing) + var/mob/M = _M + if((M.s_active == src) && M.client) + M.client.screen += I + if(!prevent_warning) // the item's user will always get a notification to_chat(user, "You put [I] into [src].") @@ -481,13 +485,7 @@ // restrict player list to include only those in view for(var/mob/M in oviewers(7, user)) M.show_message("[user] puts [I] into [src].") - orient2hud(user) - if(user) - if(user.s_active) - user.s_active.show_to(user) - I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt - I.in_inventory = TRUE update_icon() return TRUE diff --git a/code/modules/mob/inventory_procs.dm b/code/modules/mob/inventory_procs.dm index c82b9bc39f0..5cb86fb1b29 100644 --- a/code/modules/mob/inventory_procs.dm +++ b/code/modules/mob/inventory_procs.dm @@ -66,6 +66,34 @@ if(ITEM_SLOT_RIGHT_HAND) return put_in_r_hand(I) +/** + * Swaps items between hands. + * + * A separate implementation is required for this because all of the + * pre-existing equip/unEquip procs perform forceMoves we don't want. + */ +/mob/proc/swap_item_between_hands() + var/obj/item/I = get_inactive_hand() + if(!put_in_hand_check(I)) + return FALSE + + if(I == r_hand && has_left_hand()) + r_hand = null + l_hand = I + update_inv_r_hand() + update_inv_l_hand() + I.equipped(src, ITEM_SLOT_LEFT_HAND) + return TRUE + else if(I == l_hand && has_right_hand()) + l_hand = null + r_hand = I + update_inv_l_hand() + update_inv_r_hand() + I.equipped(src, ITEM_SLOT_RIGHT_HAND) + return TRUE + + return FALSE + //Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success. /mob/proc/put_in_l_hand(obj/item/W, skip_blocked_hands_check = FALSE) if(!put_in_hand_check(W, skip_blocked_hands_check)) @@ -166,13 +194,26 @@ return TRUE -/mob/proc/unEquip(obj/item/I, force, silent = FALSE) //Force overrides NODROP for things like wizarditis and admin undress. +/** + * Unequip an item from the hand that the item is found in. + * + * `force` overrides NODROP for things like wizarditis and admin undress. + * + * `destination` allows for items to be unequipped directly into storage and + * should only be used for that. + * + * Horrid stop-gap until we get atom storage or something. + */ +/mob/proc/unEquip(obj/item/I, force = FALSE, silent = FALSE, atom/destination) if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for NODROP. return 1 if(!canUnEquip(I, force)) return 0 + if(isnull(destination)) + destination = drop_location() + if(I == r_hand) r_hand = null update_inv_r_hand() @@ -181,14 +222,13 @@ update_inv_l_hand() else if(I in tkgrabbed_objects) var/obj/item/tk_grab/tkgrab = tkgrabbed_objects[I] - unEquip(tkgrab, force) + unEquip(tkgrab, force, silent, destination) if(I) if(client) client.screen -= I - var/turf/drop_loc = drop_location() - if(drop_loc) - I.forceMove(drop_loc) + if(destination) + I.forceMove(destination) else I.moveToNullspace() I.dropped(src, silent) diff --git a/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm b/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm index 0c5df6d99e9..19222c379a9 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm @@ -1,3 +1,3 @@ //can't unequip since it can't equip anything // why the fuck is this it's own file -/mob/living/carbon/alien/larva/unEquip(obj/item/I, force, silent = FALSE) +/mob/living/carbon/alien/larva/unEquip(obj/item/I, force = FALSE, silent = FALSE, atom/destination) return diff --git a/code/modules/mob/living/carbon/carbon_procs.dm b/code/modules/mob/living/carbon/carbon_procs.dm index 594e12a7963..7d9e4234a27 100644 --- a/code/modules/mob/living/carbon/carbon_procs.dm +++ b/code/modules/mob/living/carbon/carbon_procs.dm @@ -731,7 +731,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven /mob/living/carbon/get_restraining_item() return handcuffed -/mob/living/carbon/unEquip(obj/item/I, force, silent = FALSE) //THIS PROC DID NOT CALL ..() +/mob/living/carbon/unEquip(obj/item/I, force = FALSE, silent = FALSE, atom/destination) . = ..() //Sets the default return value to what the parent returns. if(!. || !I) //We don't want to set anything to null if the parent returned 0. return diff --git a/code/modules/mob/living/carbon/human/human_inventory.dm b/code/modules/mob/living/carbon/human/human_inventory.dm index 4f87fe4ff7a..dfbe9004ff0 100644 --- a/code/modules/mob/living/carbon/human/human_inventory.dm +++ b/code/modules/mob/living/carbon/human/human_inventory.dm @@ -67,7 +67,7 @@ if(ITEM_SLOT_ACCESSORY) return TRUE -/mob/living/carbon/human/unEquip(obj/item/I, force, silent = FALSE) +/mob/living/carbon/human/unEquip(obj/item/I, force = FALSE, silent = FALSE, atom/destination) . = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should. if(!. || !I) return diff --git a/code/modules/mob/living/silicon/robot/robot_inventory.dm b/code/modules/mob/living/silicon/robot/robot_inventory.dm index e3201740d5a..bbb510ccf0f 100644 --- a/code/modules/mob/living/silicon/robot/robot_inventory.dm +++ b/code/modules/mob/living/silicon/robot/robot_inventory.dm @@ -239,7 +239,7 @@ while(slot_start != slot_num) //If we wrap around without finding any free slots, just give up. return -/mob/living/silicon/robot/unEquip(obj/item/I, force, silent = FALSE) +/mob/living/silicon/robot/unEquip(obj/item/I, force = FALSE, silent = FALSE, atom/destination) if(I == module_active) uneq_active(I) return ..() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index daec7a7b43e..0d058adce0a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -504,7 +504,7 @@ if(ITEM_SLOT_COLLAR) add_collar(W) -/mob/living/simple_animal/unEquip(obj/item/I, force, silent = FALSE) +/mob/living/simple_animal/unEquip(obj/item/I, force = FALSE, silent = FALSE, atom/destination) . = ..() if(!. || !I) return diff --git a/code/modules/mob/living/simple_animal/slime/slime_mob.dm b/code/modules/mob/living/simple_animal/slime/slime_mob.dm index ce0a5d3087a..bc2278127f4 100644 --- a/code/modules/mob/living/simple_animal/slime/slime_mob.dm +++ b/code/modules/mob/living/simple_animal/slime/slime_mob.dm @@ -266,7 +266,7 @@ return return ..() -/mob/living/simple_animal/slime/unEquip(obj/item/I, force, silent = FALSE) +/mob/living/simple_animal/slime/unEquip(obj/item/I, force = FALSE, silent = FALSE, atom/destination) return /mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)