Magnetic gripper code cleanup/re-organization, and bug fix (#12592)

* Silicon gripper code cleanup/reorganization and bug fix

* review tweaks + other minor stuff

* fixes runtimes + other touchups

* oops

* more cleanup

* adds a <span>

* Lemon review updates

Makes Q drop the gripped item now insteald of having it on attack_self. Removes the configurable_items list because its not needed with this change.

Other small logic improvement in inventory.dm

* CRLF to LF

* touchups

-adds back in drop gripped item verb
-removes paperwork gripper

* add AZERTY hotkey support

Co-authored-by: SteelSlayer <SteelSlayer@users.noreply.github.com>
This commit is contained in:
SteelSlayer
2020-04-10 23:21:47 -06:00
committed by GitHub
co-authored by SteelSlayer
parent 4655e5d9d1
commit 336bfac05a
5 changed files with 63 additions and 91 deletions
+2 -4
View File
@@ -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 ..()
@@ -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, "<span class='warning'>[src] is empty.</span>")
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, "<span class='warning'>You drop [gripped_item].</span>")
gripped_item.forceMove(get_turf(src))
gripped_item = null
if(wrapped.loc != src)
wrapped = null
return
if(!silent)
to_chat(src.loc, "<span class='warning'>You drop \the [wrapped].</span>")
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, "<span class='notice'>You collect [I].</span>")
I.forceMove(src)
wrapped = I
return
gripped_item = I
else
to_chat(user, "<span class='warning'>Your gripper cannot hold \the [target].</span>")
to_chat(user, "<span class='warning'>Your gripper cannot hold [target].</span>")
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("<span class='warning'>[user] removes the power cell from [A]!</span>", "You remove the power cell.")
return TRUE
//TODO: Matter decompiler.
/obj/item/matter_decompiler
@@ -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.
@@ -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
@@ -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()