diff --git a/citadel.dme b/citadel.dme
index 76277b38c7f7..b6b545851dde 100644
--- a/citadel.dme
+++ b/citadel.dme
@@ -1580,6 +1580,7 @@
#include "code\game\objects\items\id_cards\sprite_stacks_cit.dm"
#include "code\game\objects\items\id_cards\station_ids.dm"
#include "code\game\objects\items\id_cards\syndicate_ids.dm"
+#include "code\game\objects\items\robot\gripper.dm"
#include "code\game\objects\items\robot\robot_items.dm"
#include "code\game\objects\items\robot\robot_parts.dm"
#include "code\game\objects\items\robot\robot_upgrades.dm"
diff --git a/code/__DEFINES/procs/clickcode.dm b/code/__DEFINES/procs/clickcode.dm
index 657f2dc43ba0..f8cc82c644c7 100644
--- a/code/__DEFINES/procs/clickcode.dm
+++ b/code/__DEFINES/procs/clickcode.dm
@@ -31,6 +31,8 @@
#define CLICKCHAIN_FROM_HREF (1<<4)
/// did something in the proc, logically should stop using it (the user should anyways)
#define CLICKCHAIN_DID_SOMETHING (1<<5)
+/// completely block attacking (notably, attack_mob, attack_obj) from happening by halting standard_melee_attack.
+#define CLICKCHAIN_DO_NOT_ATTACK (1<<6)
//! Reachability Depths - checked from level of DirectAccess and turf adjacency.
/// default reachability depth
diff --git a/code/_onclick/items.dm b/code/_onclick/items.dm
index dc21a49c2322..c703faac0e45 100644
--- a/code/_onclick/items.dm
+++ b/code/_onclick/items.dm
@@ -123,6 +123,8 @@
// end
if(item_flags & ITEM_NOBLUDGEON)
return NONE
+ if(clickchain_flags & CLICKCHAIN_DO_NOT_ATTACK)
+ return NONE
// todo: not hardcoding this
if(IS_PRONE(user))
mult *= 0.66
diff --git a/code/game/objects/items/robot/gripper.dm b/code/game/objects/items/robot/gripper.dm
new file mode 100644
index 000000000000..184af1b4e6c9
--- /dev/null
+++ b/code/game/objects/items/robot/gripper.dm
@@ -0,0 +1,359 @@
+//Simple borg hand.
+//Limited use.
+/obj/item/gripper
+ name = "magnetic gripper"
+ desc = "A simple grasping tool specialized in construction and engineering work."
+ description_info = "Ctrl-Clicking on the gripper will drop whatever it is holding.
\
+ Using an object on the gripper will interact with the item inside it, if it exists, instead."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "gripper"
+ item_flags = ITEM_NOBLUDGEON
+
+ //Has a list of items that it can hold.
+ var/list/can_hold = list(
+ /obj/item/cell,
+ /obj/item/airlock_electronics,
+ /obj/item/tracker_electronics,
+ /obj/item/module/power_control,
+ /obj/item/stock_parts,
+ /obj/item/frame,
+ /obj/item/camera_assembly,
+ /obj/item/tank,
+ /obj/item/circuitboard,
+ /obj/item/smes_coil,
+ /obj/item/fuelrod/,
+ /obj/item/fuel_assembly/
+ )
+
+ /// currently held item
+ VAR_PRIVATE/obj/item/wrapped
+
+/obj/item/gripper/examine(mob/user, dist)
+ . = ..()
+ if(wrapped)
+ . += "\The [src] is holding \the [wrapped]."
+ . += wrapped.examine(user)
+
+/obj/item/gripper/Destroy()
+ remove_item(drop_location())
+ return ..()
+
+/obj/item/gripper/proc/insert_item(obj/item/I)
+ if(QDELETED(I))
+ return
+ if(wrapped)
+ remove_item(drop_location())
+ wrapped = I
+ I.forceMove(src)
+ RegisterSignal(I, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED), .proc/unwrap_hook)
+
+/**
+ * newloc false to not move
+ */
+/obj/item/gripper/proc/remove_item(atom/newloc = FALSE)
+ if(!wrapped)
+ return
+ var/obj/item/old = wrapped
+ UnregisterSignal(wrapped, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
+ wrapped = null
+ switch(newloc)
+ if(null)
+ old.moveToNullspace()
+ if(FALSE)
+ else
+ old.forceMove(newloc)
+
+/obj/item/gripper/proc/unwrap_hook(datum/source)
+ ASSERT(isitem(source))
+ ASSERT(source == wrapped)
+ remove_item(FALSE)
+
+/obj/item/gripper/proc/get_item()
+ return wrapped
+
+/obj/item/gripper/CtrlClick(mob/user)
+ drop_item()
+
+/obj/item/gripper/attack_self(mob/user)
+ . = ..()
+ if(.)
+ return
+ if(wrapped)
+ return wrapped.attack_self(user)
+ return ..()
+
+/obj/item/gripper/attackby(obj/item/I, mob/living/user, list/params, clickchain_flags, damage_multiplier)
+ // todo: items should have a melee_receive_chain or something that
+ // lets us arbitrarily route melee_attack_chain to something else.
+ if(!isnull(wrapped))
+ . = wrapped.attackby(I, user, params, clickchain_flags, damage_multiplier)
+ if(.)
+ return
+ return clickchain_flags | I.afterattack(src, user, clickchain_flags, params)
+ return ..()
+
+/obj/item/gripper/melee_attack_chain(atom/target, mob/user, clickchain_flags, list/params)
+ if(!isnull(wrapped))
+ return wrapped.melee_attack_chain(target, user, clickchain_flags | CLICKCHAIN_DO_NOT_ATTACK, params)
+ return ..()
+
+/obj/item/gripper/verb/drop_item()
+ set name = "Drop Item"
+ set desc = "Release an item from your magnetic gripper."
+ set category = "Robot Commands"
+
+ if(!wrapped)
+ return
+
+ to_chat(usr, "You drop \the [wrapped].")
+ remove_item(drop_location())
+
+/obj/item/gripper/afterattack(atom/target, mob/user, clickchain_flags, list/params)
+ 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
+
+ var/obj/item/I = target
+
+ if(I.anchored)
+ to_chat(user,"You are unable to lift \the [I] from \the [I.loc].")
+ return
+
+ //Check if the item is blacklisted.
+ var/grab = 0
+ for(var/typepath in can_hold)
+ if(istype(I,typepath))
+ grab = 1
+ break
+
+ //We can grab the item, finally.
+ if(grab)
+ to_chat(user, "You collect \the [I].")
+ insert_item(I)
+ return
+ else
+ to_chat(user, "Your gripper cannot hold \the [target].")
+
+ else if(istype(target,/obj/machinery/power/apc))
+ var/obj/machinery/power/apc/A = target
+ if(A.opened)
+ if(A.cell)
+
+ insert_item(A.cell)
+ A.cell.add_fingerprint(user)
+ A.cell.update_icon()
+ A.cell = null
+
+ A.charging = 0
+ A.update_icon()
+
+ user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.")
+
+ else if(istype(target,/mob/living/silicon/robot))
+ var/mob/living/silicon/robot/A = target
+ if(A.opened)
+ if(A.cell)
+ insert_item(A.cell)
+ A.cell.add_fingerprint(user)
+ A.cell.update_icon()
+ A.updateicon()
+ A.cell = null
+
+ user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.")
+
+/obj/item/gripper/omni
+ name = "omni gripper"
+ desc = "A strange grasping tool that can hold anything a human can, but still maintains the limitations of application its more limited cousins have."
+ icon_state = "gripper-omni"
+
+ can_hold = list(/obj/item) // Testing and Event gripper.
+
+// VEEEEERY limited version for mining borgs. Basically only for swapping cells and upgrading the drills.
+/obj/item/gripper/miner
+ name = "drill maintenance gripper"
+ desc = "A simple grasping tool for the maintenance of heavy drilling machines."
+ icon_state = "gripper-mining"
+
+ can_hold = list(
+ /obj/item/cell,
+ /obj/item/stock_parts
+ )
+
+/obj/item/gripper/security
+ name = "security gripper"
+ desc = "A simple grasping tool for corporate security work."
+ icon_state = "gripper-sec"
+
+ can_hold = list(
+ /obj/item/paper,
+ /obj/item/paper_bundle,
+ /obj/item/pen,
+ /obj/item/sample,
+ /obj/item/forensics/sample_kit,
+ /obj/item/tape_recorder,
+ /obj/item/barrier_tape_roll,
+ /obj/item/uv_light
+ )
+
+/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/paper_bundle,
+ /obj/item/card/id,
+ /obj/item/book,
+ /obj/item/newspaper
+ )
+
+/obj/item/gripper/medical
+ name = "medical gripper"
+ desc = "A simple grasping tool for medical work."
+
+ can_hold = list(
+ /obj/item/reagent_containers/glass,
+ /obj/item/storage/pill_bottle,
+ /obj/item/reagent_containers/pill,
+ /obj/item/reagent_containers/blood,
+ /obj/item/stack/material/phoron,
+ /obj/item/implant,
+ /obj/item/nif
+ )
+
+/obj/item/gripper/research //A general usage gripper, used for toxins/robotics/xenobio/etc
+ name = "scientific gripper"
+ icon_state = "gripper-sci"
+ desc = "A simple grasping tool suited to assist in a wide array of research applications."
+
+ can_hold = list(
+ /obj/item/cell,
+ /obj/item/stock_parts,
+ /obj/item/mmi,
+ /obj/item/robot_parts,
+ /obj/item/borg/upgrade,
+ /obj/item/flash, //to build borgs,
+ /obj/item/disk,
+ /obj/item/circuitboard,
+ /obj/item/reagent_containers/glass,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/healthanalyzer, //to build medibots,
+ /obj/item/slime_cube,
+ /obj/item/slime_crystal,
+ /obj/item/disposable_teleporter/slime,
+ /obj/item/slimepotion,
+ /obj/item/slime_extract,
+ /obj/item/reagent_containers/food/snacks/monkeycube,
+ /obj/item/nif
+
+ )
+
+/obj/item/gripper/circuit
+ name = "circuit assembly gripper"
+ icon_state = "gripper-circ"
+ desc = "A complex grasping tool used for working with circuitry."
+
+ can_hold = list(
+ /obj/item/cell/device,
+ /obj/item/electronic_assembly,
+ /obj/item/assembly/electronic_assembly,
+ /obj/item/clothing/under/circuitry,
+ /obj/item/clothing/gloves/circuitry,
+ /obj/item/clothing/glasses/circuitry,
+ /obj/item/clothing/shoes/circuitry,
+ /obj/item/clothing/head/circuitry,
+ /obj/item/clothing/ears/circuitry,
+ /obj/item/clothing/suit/circuitry,
+ /obj/item/implant/integrated_circuit,
+ /obj/item/integrated_circuit
+
+ )
+
+/obj/item/gripper/service //Used to handle food, drinks, and seeds.
+ name = "service gripper"
+ icon_state = "gripper"
+ desc = "A simple grasping tool used to perform tasks in the service sector, such as handling food, drinks, and seeds."
+
+ can_hold = list(
+ /obj/item/reagent_containers, //simplifies a lot of redundant categorization and spaghetti with reagents
+ /obj/item/glass_extra,
+ /obj/item/seeds,
+ /obj/item/grown,
+ /obj/item/tray,
+ /obj/item/plantspray,
+ /obj/item/reagent_containers/glass,
+ /obj/item/reagent_containers/food/drinks,
+ /obj/item/storage/box/wings
+ )
+
+/obj/item/gripper/gravekeeper //Used for handling grave things, flowers, etc.
+ name = "grave gripper"
+ icon_state = "gripper"
+ desc = "A specialized grasping tool used in the preparation and maintenance of graves."
+
+ can_hold = list(
+ /obj/item/seeds,
+ /obj/item/grown,
+ /obj/item/material/gravemarker
+ )
+
+/obj/item/gripper/no_use/organ/Entered(var/atom/movable/AM)
+ ..()
+ if(istype(AM, /obj/item/organ))
+ var/obj/item/organ/O = AM
+ O.preserve(GRIPPER_TRAIT)
+
+/obj/item/gripper/no_use/organ/Exited(var/atom/movable/AM)
+ ..()
+ if(istype(AM, /obj/item/organ))
+ var/obj/item/organ/O = AM
+ O.unpreserve(GRIPPER_TRAIT)
+
+/obj/item/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item
+
+/obj/item/gripper/no_use/attack_self(mob/user)
+ return
+
+/obj/item/gripper/no_use/organ/robotics
+ name = "robotics organ gripper"
+ icon_state = "gripper-flesh"
+ desc = "A specialized grasping tool used in robotics work."
+
+ can_hold = list(
+ /obj/item/organ/external,
+ /obj/item/organ/internal/brain, //to insert into MMIs,
+ /obj/item/organ/internal/cell,
+ /obj/item/organ/internal/eyes/robot
+ )
+
+/obj/item/gripper/no_use/mech
+ name = "exosuit gripper"
+ icon_state = "gripper-mech"
+ desc = "A large, heavy-duty grasping tool used in construction of mechs."
+
+ can_hold = list(
+ /obj/item/mecha_parts/part,
+ /obj/item/mecha_parts/micro/part,
+ /obj/item/mecha_parts/mecha_equipment,
+ /obj/item/mecha_parts/mecha_tracking
+ )
+
+/obj/item/gripper/no_use/loader //This is used to disallow building with metal.
+ name = "sheet loader"
+ desc = "A specialized loading device, designed to pick up and insert sheets of materials inside machines."
+ icon_state = "gripper-sheet"
+
+ can_hold = list(
+ /obj/item/stack/material
+ )
+
+/obj/item/gripper/no_use/organ
+ name = "organ gripper"
+ icon_state = "gripper-flesh"
+ desc = "A specialized grasping tool used to preserve and manipulate organic material."
+
+ can_hold = list(
+ /obj/item/organ
+ )
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 dde8157306f5..10cfdb456d18 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
@@ -1,383 +1,3 @@
-//Simple borg hand.
-//Limited use.
-/obj/item/gripper
- name = "magnetic gripper"
- desc = "A simple grasping tool specialized in construction and engineering work."
- description_info = "Ctrl-Clicking on the gripper will drop whatever it is holding.
\
- Using an object on the gripper will interact with the item inside it, if it exists, instead."
- icon = 'icons/obj/device.dmi'
- icon_state = "gripper"
- item_flags = ITEM_NOBLUDGEON
-
- //Has a list of items that it can hold.
- var/list/can_hold = list(
- /obj/item/cell,
- /obj/item/airlock_electronics,
- /obj/item/tracker_electronics,
- /obj/item/module/power_control,
- /obj/item/stock_parts,
- /obj/item/frame,
- /obj/item/camera_assembly,
- /obj/item/tank,
- /obj/item/circuitboard,
- /obj/item/smes_coil,
- /obj/item/fuelrod/,
- /obj/item/fuel_assembly/
- )
-
- /// currently held item
- VAR_PRIVATE/obj/item/wrapped
-
- var/force_holder = null //
-
-/obj/item/gripper/examine(mob/user, dist)
- . = ..()
- if(wrapped)
- . += "\The [src] is holding \the [wrapped]."
- . += wrapped.examine(user)
-
-/obj/item/gripper/Destroy()
- remove_item(drop_location())
- return ..()
-
-/obj/item/gripper/proc/insert_item(obj/item/I)
- if(QDELETED(I))
- return
- if(wrapped)
- remove_item(drop_location())
- wrapped = I
- I.forceMove(src)
- RegisterSignal(I, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED), .proc/unwrap_hook)
-
-/**
- * newloc false to not move
- */
-/obj/item/gripper/proc/remove_item(atom/newloc = FALSE)
- if(!wrapped)
- return
- var/obj/item/old = wrapped
- UnregisterSignal(wrapped, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
- wrapped = null
- switch(newloc)
- if(null)
- old.moveToNullspace()
- if(FALSE)
- else
- old.forceMove(newloc)
-
-/obj/item/gripper/proc/unwrap_hook(datum/source)
- ASSERT(isitem(source))
- ASSERT(source == wrapped)
- remove_item(FALSE)
-
-/obj/item/gripper/proc/get_item()
- return wrapped
-
-/obj/item/gripper/CtrlClick(mob/user)
- drop_item()
-
-/obj/item/gripper/omni
- name = "omni gripper"
- desc = "A strange grasping tool that can hold anything a human can, but still maintains the limitations of application its more limited cousins have."
- icon_state = "gripper-omni"
-
- can_hold = list(/obj/item) // Testing and Event gripper.
-
-// VEEEEERY limited version for mining borgs. Basically only for swapping cells and upgrading the drills.
-/obj/item/gripper/miner
- name = "drill maintenance gripper"
- desc = "A simple grasping tool for the maintenance of heavy drilling machines."
- icon_state = "gripper-mining"
-
- can_hold = list(
- /obj/item/cell,
- /obj/item/stock_parts
- )
-
-/obj/item/gripper/security
- name = "security gripper"
- desc = "A simple grasping tool for corporate security work."
- icon_state = "gripper-sec"
-
- can_hold = list(
- /obj/item/paper,
- /obj/item/paper_bundle,
- /obj/item/pen,
- /obj/item/sample,
- /obj/item/forensics/sample_kit,
- /obj/item/tape_recorder,
- /obj/item/barrier_tape_roll,
- /obj/item/uv_light
- )
-
-/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/paper_bundle,
- /obj/item/card/id,
- /obj/item/book,
- /obj/item/newspaper
- )
-
-/obj/item/gripper/medical
- name = "medical gripper"
- desc = "A simple grasping tool for medical work."
-
- can_hold = list(
- /obj/item/reagent_containers/glass,
- /obj/item/storage/pill_bottle,
- /obj/item/reagent_containers/pill,
- /obj/item/reagent_containers/blood,
- /obj/item/stack/material/phoron,
- /obj/item/implant,
- /obj/item/nif
- )
-
-/obj/item/gripper/research //A general usage gripper, used for toxins/robotics/xenobio/etc
- name = "scientific gripper"
- icon_state = "gripper-sci"
- desc = "A simple grasping tool suited to assist in a wide array of research applications."
-
- can_hold = list(
- /obj/item/cell,
- /obj/item/stock_parts,
- /obj/item/mmi,
- /obj/item/robot_parts,
- /obj/item/borg/upgrade,
- /obj/item/flash, //to build borgs,
- /obj/item/disk,
- /obj/item/circuitboard,
- /obj/item/reagent_containers/glass,
- /obj/item/assembly/prox_sensor,
- /obj/item/healthanalyzer, //to build medibots,
- /obj/item/slime_cube,
- /obj/item/slime_crystal,
- /obj/item/disposable_teleporter/slime,
- /obj/item/slimepotion,
- /obj/item/slime_extract,
- /obj/item/reagent_containers/food/snacks/monkeycube,
- /obj/item/nif
-
- )
-
-/obj/item/gripper/circuit
- name = "circuit assembly gripper"
- icon_state = "gripper-circ"
- desc = "A complex grasping tool used for working with circuitry."
-
- can_hold = list(
- /obj/item/cell/device,
- /obj/item/electronic_assembly,
- /obj/item/assembly/electronic_assembly,
- /obj/item/clothing/under/circuitry,
- /obj/item/clothing/gloves/circuitry,
- /obj/item/clothing/glasses/circuitry,
- /obj/item/clothing/shoes/circuitry,
- /obj/item/clothing/head/circuitry,
- /obj/item/clothing/ears/circuitry,
- /obj/item/clothing/suit/circuitry,
- /obj/item/implant/integrated_circuit,
- /obj/item/integrated_circuit
-
- )
-
-/obj/item/gripper/service //Used to handle food, drinks, and seeds.
- name = "service gripper"
- icon_state = "gripper"
- desc = "A simple grasping tool used to perform tasks in the service sector, such as handling food, drinks, and seeds."
-
- can_hold = list(
- /obj/item/reagent_containers, //simplifies a lot of redundant categorization and spaghetti with reagents
- /obj/item/glass_extra,
- /obj/item/seeds,
- /obj/item/grown,
- /obj/item/tray,
- /obj/item/plantspray,
- /obj/item/reagent_containers/glass,
- /obj/item/reagent_containers/food/drinks,
- /obj/item/storage/box/wings
- )
-
-/obj/item/gripper/gravekeeper //Used for handling grave things, flowers, etc.
- name = "grave gripper"
- icon_state = "gripper"
- desc = "A specialized grasping tool used in the preparation and maintenance of graves."
-
- can_hold = list(
- /obj/item/seeds,
- /obj/item/grown,
- /obj/item/material/gravemarker
- )
-
-/obj/item/gripper/no_use/organ
- name = "organ gripper"
- icon_state = "gripper-flesh"
- desc = "A specialized grasping tool used to preserve and manipulate organic material."
-
- can_hold = list(
- /obj/item/organ
- )
-
-/obj/item/gripper/no_use/organ/Entered(var/atom/movable/AM)
- ..()
- if(istype(AM, /obj/item/organ))
- var/obj/item/organ/O = AM
- O.preserve(GRIPPER_TRAIT)
-
-/obj/item/gripper/no_use/organ/Exited(var/atom/movable/AM)
- ..()
- if(istype(AM, /obj/item/organ))
- var/obj/item/organ/O = AM
- O.unpreserve(GRIPPER_TRAIT)
-
-/obj/item/gripper/no_use/organ/robotics
- name = "robotics organ gripper"
- icon_state = "gripper-flesh"
- desc = "A specialized grasping tool used in robotics work."
-
- can_hold = list(
- /obj/item/organ/external,
- /obj/item/organ/internal/brain, //to insert into MMIs,
- /obj/item/organ/internal/cell,
- /obj/item/organ/internal/eyes/robot
- )
-
-/obj/item/gripper/no_use/mech
- name = "exosuit gripper"
- icon_state = "gripper-mech"
- desc = "A large, heavy-duty grasping tool used in construction of mechs."
-
- can_hold = list(
- /obj/item/mecha_parts/part,
- /obj/item/mecha_parts/micro/part,
- /obj/item/mecha_parts/mecha_equipment,
- /obj/item/mecha_parts/mecha_tracking
- )
-
-/obj/item/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item
-
-/obj/item/gripper/no_use/attack_self(mob/user)
- . = ..()
- if(.)
- return
- return
-
-/obj/item/gripper/no_use/loader //This is used to disallow building with metal.
- name = "sheet loader"
- desc = "A specialized loading device, designed to pick up and insert sheets of materials inside machines."
- icon_state = "gripper-sheet"
-
- can_hold = list(
- /obj/item/stack/material
- )
-
-/obj/item/gripper/attack_self(mob/user)
- . = ..()
- if(.)
- return
- if(wrapped)
- return wrapped.attack_self(user)
- return ..()
-
-/obj/item/gripper/attackby(var/obj/item/O, var/mob/user)
- if(wrapped) // We're interacting with the item inside. If you can hold a cup with 2 fingers and stick a straw in it, you could do that with a gripper and another robotic arm.
- var/resolved = wrapped.attackby(O, user)
- if(!resolved && wrapped && O)
- O.afterattack(wrapped,user,1)
- return resolved
- return ..()
-
-/obj/item/gripper/verb/drop_item()
- set name = "Drop Item"
- set desc = "Release an item from your magnetic gripper."
- set category = "Robot Commands"
-
- if(!wrapped)
- return
-
- to_chat(usr, "You drop \the [wrapped].")
- remove_item(drop_location())
-
-/obj/item/gripper/attack_mob(mob/target, mob/user, clickchain_flags, list/params, mult, target_zone, intent)
- if(wrapped) //The damage_force of the wrapped obj gets set to zero during the attack() and afterattack().
- force_holder = wrapped.damage_force
- wrapped.damage_force = 0
- target.attackby(wrapped, user, params, clickchain_flags) //attackby reportedly gets procced by being clicked on, at least according to Anewbe.
- return 1
- return 0
-
-/obj/item/gripper/afterattack(atom/target, mob/user, clickchain_flags, list/params)
- if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY))
- return // This will prevent them using guns at range but adminbuse can add them directly to modules, so eh.
-
-
- if(wrapped) //Already have an item.
- //Pass the attack on to the target. This might delete/relocate wrapped.
- var/resolved = target.attackby(wrapped, user)
- if(!resolved && wrapped && target)
- wrapped.afterattack(target,user,1)
- //wrapped's damage_force was set to zero. This resets it to the value it had before.
- if(wrapped)
- wrapped.damage_force = force_holder
- force_holder = null
-
- 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
-
- var/obj/item/I = target
-
- if(I.anchored)
- to_chat(user,"You are unable to lift \the [I] from \the [I.loc].")
- return
-
- //Check if the item is blacklisted.
- var/grab = 0
- for(var/typepath in can_hold)
- if(istype(I,typepath))
- grab = 1
- break
-
- //We can grab the item, finally.
- if(grab)
- to_chat(user, "You collect \the [I].")
- insert_item(I)
- return
- else
- to_chat(user, "Your gripper cannot hold \the [target].")
-
- else if(istype(target,/obj/machinery/power/apc))
- var/obj/machinery/power/apc/A = target
- if(A.opened)
- if(A.cell)
-
- insert_item(A.cell)
- A.cell.add_fingerprint(user)
- A.cell.update_icon()
- A.cell = null
-
- A.charging = 0
- A.update_icon()
-
- user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.")
-
- else if(istype(target,/mob/living/silicon/robot))
- var/mob/living/silicon/robot/A = target
- if(A.opened)
- if(A.cell)
- insert_item(A.cell)
- A.cell.add_fingerprint(user)
- A.cell.update_icon()
- A.updateicon()
- A.cell = null
-
- user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.")
//TODO: Matter decompiler.
/obj/item/matter_decompiler