diff --git a/code/modules/keybindings/bindings_robot.dm b/code/modules/keybindings/bindings_robot.dm index 073f0ccae84..f85264308a0 100644 --- a/code/modules/keybindings/bindings_robot.dm +++ b/code/modules/keybindings/bindings_robot.dm @@ -11,10 +11,8 @@ return if("Q") if(!(client.prefs.toggles & AZERTY)) - uneq_active() - return + on_drop_hotkey_press() // User is in QWERTY hotkey mode. if("A") if(client.prefs.toggles & AZERTY) - uneq_active() - return + on_drop_hotkey_press() return ..() diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index d200bdb075a..7958f983805 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -30,29 +30,22 @@ /obj/item/circuitboard, /obj/item/stack/tile/light, /obj/item/stack/ore/bluespace_crystal - ) + ) //Item currently being held. - var/obj/item/wrapped = null - -/obj/item/gripper/paperwork - name = "paperwork gripper" - desc = "A simple grasping tool for clerical work." - - can_hold = list( - /obj/item/clipboard, - /obj/item/paper, - /obj/item/card/id - ) + var/obj/item/gripped_item = null /obj/item/gripper/medical name = "medical gripper" desc = "A grasping tool used to help patients up once surgery is complete." can_hold = list() -/obj/item/gripper/medical/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params) +/obj/item/gripper/medical/attack_self(mob/user) + return + +/obj/item/gripper/medical/afterattack(atom/target, mob/living/user, proximity, params) var/mob/living/carbon/human/H - if(!wrapped && proximity && target && ishuman(target)) + if(!gripped_item && proximity && target && ishuman(target)) H = target if(H.lying) H.AdjustSleeping(-5) @@ -71,98 +64,69 @@ ..() can_hold = typecacheof(can_hold) -/obj/item/gripper/attack_self(mob/user as mob) - if(wrapped) - wrapped.attack_self(user) - /obj/item/gripper/verb/drop_item() - set name = "Drop Gripped Item" set desc = "Release an item from your magnetic gripper." set category = "Drone" - drop_item_p() + drop_gripped_item() -// The "p" stands for proc, since I was having annoying weird stuff happening with this in the verb -// when trying to have default values for arguments and stuff -/obj/item/gripper/proc/drop_item_p(var/silent = 0) +/obj/item/gripper/attack_self(mob/user) + if(gripped_item) + gripped_item.attack_self(user) + else + to_chat(user, "[src] is empty.") - if(!wrapped) - //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z - for(var/obj/item/thing in src.contents) - thing.forceMove(get_turf(src)) - return +/obj/item/gripper/proc/drop_gripped_item(silent = FALSE) + if(gripped_item) + if(!silent) + to_chat(loc, "You drop [gripped_item].") + gripped_item.forceMove(get_turf(src)) + gripped_item = null - if(wrapped.loc != src) - wrapped = null - return - - if(!silent) - to_chat(src.loc, "You drop \the [wrapped].") - wrapped.forceMove(get_turf(src)) - wrapped = null - -/obj/item/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) +/obj/item/gripper/attack(mob/living/carbon/M, mob/living/carbon/user) return -/obj/item/gripper/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params) +/// Grippers are snowflakey so this is needed to to prevent forceMoving grippers after `if(!user.drop_item())` checks done in certain attackby's. +/obj/item/gripper/forceMove(atom/destination) + return + +/obj/item/gripper/afterattack(atom/target, mob/living/user, proximity, params) if(!target || !proximity) //Target is invalid or we are not adjacent. - return + return FALSE - //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z - if(!wrapped) - for(var/obj/item/thing in src.contents) - wrapped = thing - break + if(gripped_item) //Already have an item. - if(wrapped) //Already have an item. - - //Temporary put wrapped into user so target's attackby() checks pass. - wrapped.forceMove(user) - - //Pass the attack on to the target. This might delete/relocate wrapped. - if(!target.attackby(wrapped, user, params) && target && wrapped) - // If the attackby didn't resolve or delete the target or wrapped, afterattack + //Pass the attack on to the target. This might delete/relocate gripped_item. + if(!target.attackby(gripped_item, user, params)) + // If the attackby didn't resolve or delete the target or gripped_item, afterattack // (Certain things, such as mountable frames, rely on afterattack) - wrapped.afterattack(target, user, 1, params) + gripped_item?.afterattack(target, user, 1, params) - //If wrapped did neither get deleted nor put into target, put it back into the gripper. - if(wrapped && user && (wrapped.loc == user)) - wrapped.forceMove(src) - else - wrapped = null - return - - else if(istype(target,/obj/item)) //Check that we're not pocketing a mob. - - //...and that the item is not in a container. - if(!isturf(target.loc)) - return + //If gripped_item either didn't get deleted, or it failed to be transfered to its target + if(!gripped_item && contents.len) + gripped_item = contents[1] + return FALSE + else if(gripped_item && !contents.len) + gripped_item = null + else if(istype(target, /obj/item)) //Check that we're not pocketing a mob. var/obj/item/I = target - - //Check if the item is blacklisted. - var/grab = 0 - if(can_hold.len) - if(is_type_in_typecache(I, can_hold)) - grab = 1 - - //We can grab the item, finally. - if(grab) - to_chat(user, "You collect \the [I].") + if(is_type_in_typecache(I, can_hold)) // Make sure the item is something the gripper can hold + to_chat(user, "You collect [I].") I.forceMove(src) - wrapped = I - return + gripped_item = I else - to_chat(user, "Your gripper cannot hold \the [target].") + to_chat(user, "Your gripper cannot hold [target].") + return FALSE else if(istype(target,/obj/machinery/power/apc)) var/obj/machinery/power/apc/A = target if(A.opened) if(A.cell) - wrapped = A.cell + gripped_item = A.cell A.cell.add_fingerprint(user) A.cell.update_icon() @@ -173,6 +137,7 @@ A.update_icon() user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.") + return TRUE //TODO: Matter decompiler. /obj/item/matter_decompiler diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 16d9080ef7e..a68da651ee9 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -115,11 +115,11 @@ return 0 /mob/living/silicon/robot/drop_item() - var/obj/item/I = get_active_hand() - if(istype(I, /obj/item/gripper)) - var/obj/item/gripper/G = I - G.drop_item_p(silent = 1) - return + var/obj/item/gripper/G = get_active_hand() + if(istype(G)) + G.drop_gripped_item(silent = TRUE) + return TRUE // The gripper is special because it has a normal item inside that we can drop. + return FALSE // All robot inventory items have NODROP, so they should return FALSE. //Helper procs for cyborg modules on the UI. //These are hackish but they help clean up code elsewhere. diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index a8bad5ebc03..270ee325bf9 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1472,3 +1472,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT) sync_lighting_plane_alpha() + +/// Used in `robot_bindings.dm` when the user presses "A" if on AZERTY mode, or "Q" on QWERTY mode. +/mob/living/silicon/robot/proc/on_drop_hotkey_press() + var/obj/item/gripper/G = get_active_hand() + if(istype(G) && G.gripped_item) + G.drop_gripped_item() // if the active module is a gripper, try to drop its held item. + else + uneq_active() // else unequip the module and put it back into the robot's inventory. + return diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 47dcb93cef5..3260775c674 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -230,7 +230,7 @@ /obj/item/robot_module/engineering/handle_death() var/obj/item/gripper/G = locate(/obj/item/gripper) in modules if(G) - G.drop_item() + G.drop_gripped_item(silent = TRUE) /obj/item/robot_module/security name = "security robot module" @@ -578,7 +578,7 @@ /obj/item/robot_module/drone/handle_death() var/obj/item/gripper/G = locate(/obj/item/gripper) in modules if(G) - G.drop_item() + G.drop_gripped_item(silent = TRUE) //checks whether this item is a module of the robot it is located in. /obj/item/proc/is_robot_module()