diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm
index 7809610e6ab..2348bd49f19 100644
--- a/code/__DEFINES/tools.dm
+++ b/code/__DEFINES/tools.dm
@@ -8,6 +8,7 @@
#define TOOL_ANALYZER "analyzer"
#define TOOL_MINING "mining"
#define TOOL_SHOVEL "shovel"
+#define TOOL_DRAPES "surgicaldrapes"
#define TOOL_RETRACTOR "retractor"
#define TOOL_HEMOSTAT "hemostat"
#define TOOL_CAUTERY "cautery"
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index beeb1599f20..a5c2035b939 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -8,6 +8,11 @@
* * [/obj/item/proc/afterattack]. The return value does not matter.
*/
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
+ //Proxy replaces src cause it returns an atom that will attack the target on our behalf
+ var/obj/item/source_atom = get_proxy_attacker_for(target, user)
+ if(source_atom != src) //if we are someone else then call that attack chain else we can proceed with the usual stuff
+ return source_atom.melee_attack_chain(user, target, params)
+
var/list/modifiers = params2list(params)
var/is_right_clicking = LAZYACCESS(modifiers, RIGHT_CLICK)
diff --git a/code/datums/components/material/remote_materials.dm b/code/datums/components/material/remote_materials.dm
index 568b018e58b..d2804f97df1 100644
--- a/code/datums/components/material/remote_materials.dm
+++ b/code/datums/components/material/remote_materials.dm
@@ -144,12 +144,10 @@ handles linking back and forth.
return COMPONENT_NO_AFTERATTACK
-/datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/I)
+/datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/multitool/M)
SIGNAL_HANDLER
- if(!I.multitool_check_buffer(user, I))
- return ITEM_INTERACT_BLOCKING
- var/obj/item/multitool/M = I
+ . = ITEM_INTERACT_BLOCKING
if (!QDELETED(M.buffer) && istype(M.buffer, /obj/machinery/ore_silo))
if (silo == M.buffer)
to_chat(user, span_warning("[parent] is already connected to [silo]!"))
diff --git a/code/datums/components/surgery_initiator.dm b/code/datums/components/surgery_initiator.dm
index de3f83739e5..848bfd021ee 100644
--- a/code/datums/components/surgery_initiator.dm
+++ b/code/datums/components/surgery_initiator.dm
@@ -134,15 +134,7 @@
if(is_robotic)
required_tool_type = TOOL_SCREWDRIVER
- if(iscyborg(user))
- var/has_cautery = FALSE
- for(var/obj/item/borg/cyborg_omnitool/toolarm in user.held_items)
- if(toolarm.selected && istype(toolarm.selected, /obj/item/cautery))
- has_cautery = TRUE
- if(!has_cautery)
- patient.balloon_alert(user, "need a cautery in an inactive slot to stop the surgery!")
- return
- else if(!close_tool || close_tool.tool_behaviour != required_tool_type)
+ if(!close_tool || close_tool.tool_behaviour != required_tool_type)
patient.balloon_alert(user, "need a [is_robotic ? "screwdriver": "cautery"] in your inactive hand to stop the surgery!")
return
@@ -226,7 +218,7 @@
)
/datum/component/surgery_initiator/ui_data(mob/user)
- var/mob/living/surgery_target = surgery_target_ref.resolve()
+ var/mob/living/surgery_target = surgery_target_ref?.resolve()
var/list/surgeries = list()
if (!isnull(surgery_target))
@@ -253,10 +245,6 @@
return ..()
/datum/component/surgery_initiator/ui_status(mob/user, datum/ui_state/state)
- var/obj/item/item_parent = parent
- if (user != item_parent.loc)
- return UI_CLOSE
-
var/mob/living/surgery_target = surgery_target_ref?.resolve()
if (isnull(surgery_target))
return UI_CLOSE
@@ -271,7 +259,8 @@
return FALSE
// The item was moved somewhere else
- if (!(parent in user))
+ var/atom/movable/tool = parent
+ if (tool.loc != user)
return FALSE
// While we were choosing, another surgery was started at the same location
diff --git a/code/game/atom/atom_tool_acts.dm b/code/game/atom/atom_tool_acts.dm
index d055f22759e..10bed5a4077 100644
--- a/code/game/atom/atom_tool_acts.dm
+++ b/code/game/atom/atom_tool_acts.dm
@@ -276,14 +276,6 @@
/atom/proc/multitool_act_secondary(mob/living/user, obj/item/tool)
return
-///Check if an item supports a data buffer (is a multitool)
-/atom/proc/multitool_check_buffer(user, obj/item/multitool, silent = FALSE)
- if(!istype(multitool, /obj/item/multitool))
- if(user && !silent)
- to_chat(user, span_warning("[multitool] has no data buffer!"))
- return FALSE
- return TRUE
-
/// Called on an object when a tool with screwdriver capabilities is used to left click an object
/atom/proc/screwdriver_act(mob/living/user, obj/item/tool)
return
diff --git a/code/game/machinery/botlaunchpad.dm b/code/game/machinery/botlaunchpad.dm
index c8004af84ba..fecca2a2548 100644
--- a/code/game/machinery/botlaunchpad.dm
+++ b/code/game/machinery/botlaunchpad.dm
@@ -21,17 +21,14 @@
/obj/machinery/botpad/crowbar_act(mob/user, obj/item/tool)
return default_deconstruction_crowbar(tool)
-/obj/machinery/botpad/multitool_act(mob/living/user, obj/item/tool)
+/obj/machinery/botpad/multitool_act(mob/living/user, obj/item/multitool/tool)
if(!panel_open)
- return
- if(!multitool_check_buffer(user, tool))
- return
+ return NONE
var/obj/item/multitool/multitool = tool
multitool.set_buffer(src)
balloon_alert(user, "saved to multitool buffer")
return ITEM_INTERACT_SUCCESS
-
// Checks the turf for a bot and launches it if it's the only mob on the pad.
/obj/machinery/botpad/proc/launch(mob/living/user)
var/turf/reverse_turf = get_turf(user)
diff --git a/code/game/machinery/computer/launchpad_control.dm b/code/game/machinery/computer/launchpad_control.dm
index 54ff5e0f313..7c6d1307b76 100644
--- a/code/game/machinery/computer/launchpad_control.dm
+++ b/code/game/machinery/computer/launchpad_control.dm
@@ -58,20 +58,16 @@
to_chat(user, span_warning("You are too primitive to use this computer!"))
return
-/obj/machinery/computer/launchpad/attackby(obj/item/W, mob/user, params)
- if(W.tool_behaviour == TOOL_MULTITOOL)
- if(!multitool_check_buffer(user, W))
- return
- var/obj/item/multitool/M = W
- if(M.buffer && istype(M.buffer, /obj/machinery/launchpad))
- if(LAZYLEN(launchpads) < maximum_pads)
- launchpads |= M.buffer
- M.set_buffer(null)
- to_chat(user, span_notice("You upload the data from the [W.name]'s buffer."))
- else
- to_chat(user, span_warning("[src] cannot handle any more connections!"))
- else
- return ..()
+/obj/machinery/computer/launchpad/multitool_act(mob/living/user, obj/item/multitool/tool)
+ . = NONE
+ if(!istype(tool.buffer, /obj/machinery/launchpad))
+ return
+
+ if(LAZYLEN(launchpads) < maximum_pads)
+ launchpads |= tool.buffer
+ tool.set_buffer(null)
+ to_chat(user, span_notice("You upload the data from the [tool] buffer."))
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/computer/launchpad/proc/pad_exists(number)
var/obj/machinery/launchpad/pad = launchpads[number]
diff --git a/code/game/machinery/computer/mechlaunchpad.dm b/code/game/machinery/computer/mechlaunchpad.dm
index 7b80b6e95c8..46c0045fb35 100644
--- a/code/game/machinery/computer/mechlaunchpad.dm
+++ b/code/game/machinery/computer/mechlaunchpad.dm
@@ -86,28 +86,32 @@
continue
return found_mechpad
-/obj/machinery/computer/mechpad/multitool_act(mob/living/user, obj/item/tool)
- if(!multitool_check_buffer(user, tool))
+/obj/machinery/computer/mechpad/multitool_act(mob/living/user, obj/item/multitool/multitool)
+ . = NONE
+ if(!istype(multitool.buffer, /obj/machinery/mechpad))
return
- var/obj/item/multitool/multitool = tool
- if(istype(multitool.buffer, /obj/machinery/mechpad))
- var/obj/machinery/mechpad/buffered_pad = multitool.buffer
- if(!(mechpads.len < maximum_pads))
- to_chat(user, span_warning("[src] cannot handle any more connections!"))
- return TRUE
- if(buffered_pad == connected_mechpad)
- to_chat(user, span_warning("[src] cannot connect to its own mechpad!"))
- else if(!connected_mechpad && buffered_pad == find_pad())
- if(buffered_pad in mechpads)
- remove_pad(buffered_pad)
- connect_launchpad(buffered_pad)
- multitool.set_buffer(null)
- to_chat(user, span_notice("You connect the console to the pad with data from the [multitool.name]'s buffer."))
- else
- add_pad(buffered_pad)
- multitool.set_buffer(null)
- to_chat(user, span_notice("You upload the data from the [multitool.name]'s buffer."))
- return TRUE
+
+ var/obj/machinery/mechpad/buffered_pad = multitool.buffer
+ if(!(mechpads.len < maximum_pads))
+ to_chat(user, span_warning("[src] cannot handle any more connections!"))
+ return ITEM_INTERACT_SUCCESS
+
+ if(buffered_pad == connected_mechpad)
+ to_chat(user, span_warning("[src] cannot connect to its own mechpad!"))
+ return ITEM_INTERACT_BLOCKING
+
+ if(!connected_mechpad && buffered_pad == find_pad())
+ if(buffered_pad in mechpads)
+ remove_pad(buffered_pad)
+ connect_launchpad(buffered_pad)
+ multitool.set_buffer(null)
+ to_chat(user, span_notice("You connect the console to the pad with data from the [multitool.name]'s buffer."))
+ return ITEM_INTERACT_SUCCESS
+
+ add_pad(buffered_pad)
+ multitool.set_buffer(null)
+ to_chat(user, span_notice("You upload the data from the [multitool.name]'s buffer."))
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/computer/mechpad/proc/add_pad(obj/machinery/mechpad/pad)
mechpads += pad
diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm
index 444e44125c8..391cf38b74b 100644
--- a/code/game/machinery/launch_pad.dm
+++ b/code/game/machinery/launch_pad.dm
@@ -66,6 +66,15 @@
if(in_range(user, src) || isobserver(user))
. += span_notice("The status display reads: Maximum range: [range] units.")
+/obj/machinery/launchpad/multitool_act(mob/living/user, obj/item/multitool/multi)
+ . = NONE
+ if(!panel_open)
+ return
+
+ multi.set_buffer(src)
+ balloon_alert(user, "saved to buffer")
+ return ITEM_INTERACT_SUCCESS
+
/obj/machinery/launchpad/attackby(obj/item/weapon, mob/user, params)
if(!stationary)
return ..()
@@ -74,14 +83,6 @@
update_indicator()
return
- if(panel_open && weapon.tool_behaviour == TOOL_MULTITOOL)
- if(!multitool_check_buffer(user, weapon))
- return
- var/obj/item/multitool/multi = weapon
- multi.set_buffer(src)
- balloon_alert(user, "saved to buffer")
- return TRUE
-
if(default_deconstruction_crowbar(weapon))
return
diff --git a/code/game/machinery/mechlaunchpad.dm b/code/game/machinery/mechlaunchpad.dm
index b8c282ae22c..cbdc34d8648 100644
--- a/code/game/machinery/mechlaunchpad.dm
+++ b/code/game/machinery/mechlaunchpad.dm
@@ -30,15 +30,14 @@
if(default_deconstruction_crowbar(tool))
return TRUE
-/obj/machinery/mechpad/multitool_act(mob/living/user, obj/item/tool)
+/obj/machinery/mechpad/multitool_act(mob/living/user, obj/item/multitool/multitool)
+ . = NONE
if(!panel_open)
return
- if(!multitool_check_buffer(user, tool))
- return
- var/obj/item/multitool/multitool = tool
+
multitool.set_buffer(src)
balloon_alert(user, "saved to multitool buffer")
- return TRUE
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/mechpad/wirecutter_act(mob/living/user, obj/item/tool)
if(!panel_open)
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index d41064ba2ef..c9694730a3f 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -317,6 +317,15 @@ DEFINE_BITFIELD(turret_flags, list(
remove_control()
check_should_process()
+/obj/machinery/porta_turret/multitool_act(mob/living/user, obj/item/multitool/tool)
+ . = NONE
+ if(locked)
+ return
+
+ tool.set_buffer(src)
+ balloon_alert(user, "saved to multitool buffer")
+ return ITEM_INTERACT_SUCCESS
+
/obj/machinery/porta_turret/attackby(obj/item/I, mob/user, params)
if(machine_stat & BROKEN)
if(I.tool_behaviour == TOOL_CROWBAR)
@@ -364,12 +373,6 @@ DEFINE_BITFIELD(turret_flags, list(
to_chat(user, span_notice("Controls are now [locked ? "locked" : "unlocked"]."))
else
to_chat(user, span_alert("Access denied."))
- else if(I.tool_behaviour == TOOL_MULTITOOL && !locked)
- if(!multitool_check_buffer(user, I))
- return
- var/obj/item/multitool/M = I
- M.set_buffer(src)
- balloon_alert(user, "saved to multitool buffer")
else
return ..()
@@ -967,18 +970,19 @@ DEFINE_BITFIELD(turret_flags, list(
. += {"[span_notice("Ctrl-click [src] to [ enabled ? "disable" : "enable"] turrets.")]
[span_notice("Alt-click [src] to set turrets to [ lethal ? "stun" : "kill"].")]"}
-/obj/machinery/turretid/attackby(obj/item/attacking_item, mob/user, params)
+/obj/machinery/turretid/multitool_act(mob/living/user, obj/item/multitool/multi_tool)
+ . = NONE
if(machine_stat & BROKEN)
return
- if(attacking_item.tool_behaviour == TOOL_MULTITOOL)
- if(!multitool_check_buffer(user, attacking_item))
- return
- var/obj/item/multitool/M = attacking_item
- if(M.buffer && istype(M.buffer, /obj/machinery/porta_turret))
- turrets |= WEAKREF(M.buffer)
- to_chat(user, span_notice("You link \the [M.buffer] with \the [src]."))
- return
+ if(multi_tool.buffer && istype(multi_tool.buffer, /obj/machinery/porta_turret))
+ turrets |= WEAKREF(multi_tool.buffer)
+ to_chat(user, span_notice("You link \the [multi_tool.buffer] with \the [src]."))
+ return ITEM_INTERACT_SUCCESS
+
+/obj/machinery/turretid/attackby(obj/item/attacking_item, mob/user, params)
+ if(machine_stat & BROKEN)
+ return
if (issilicon(user))
return attack_hand(user)
diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm
index e81c13af608..ad3111b330b 100644
--- a/code/game/machinery/porta_turret/portable_turret_cover.dm
+++ b/code/game/machinery/porta_turret/portable_turret_cover.dm
@@ -36,6 +36,15 @@
/obj/machinery/porta_turret_cover/attack_ghost(mob/user)
return ..() || parent_turret.attack_ghost(user)
+/obj/machinery/porta_turret_cover/multitool_act(mob/living/user, obj/item/multitool/multi_tool)
+ . = NONE
+ if(parent_turret.locked)
+ return
+
+ multi_tool.set_buffer(parent_turret)
+ balloon_alert(user, "saved to multitool buffer")
+ return ITEM_INTERACT_SUCCESS
+
/obj/machinery/porta_turret_cover/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_WRENCH && !parent_turret.on)
if(parent_turret.raised)
@@ -61,13 +70,6 @@
to_chat(user, span_notice("Access denied."))
return
- if(I.tool_behaviour == TOOL_MULTITOOL && !parent_turret.locked)
- if(!multitool_check_buffer(user, I))
- return
- var/obj/item/multitool/M = I
- M.set_buffer(parent_turret)
- balloon_alert(user, "saved to multitool buffer")
- return
return ..()
/obj/machinery/porta_turret_cover/attacked_by(obj/item/I, mob/user)
diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm
index 1c014927e62..f5f5851b758 100644
--- a/code/game/machinery/quantum_pad.dm
+++ b/code/game/machinery/quantum_pad.dm
@@ -53,37 +53,30 @@
teleport_cooldown = initial(teleport_cooldown)
teleport_cooldown -= (E * 100)
-/obj/machinery/quantumpad/attackby(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, "qpad-idle-open", "qpad-idle", I))
+/obj/machinery/quantumpad/multitool_act(mob/living/user, obj/item/multitool/multi_tool)
+ if(panel_open)
+ multi_tool.set_buffer(src)
+ balloon_alert(user, "saved to multitool buffer")
+ to_chat(user, span_notice("You save the data in [multi_tool] buffer. It can now be saved to pads with closed panels."))
+ return ITEM_INTERACT_SUCCESS
+
+ if(istype(multi_tool.buffer, /obj/machinery/quantumpad))
+ if(multi_tool.buffer == src)
+ balloon_alert(user, "cannot link to self!")
+ return ITEM_INTERACT_BLOCKING
+ linked_pad = multi_tool.buffer
+ balloon_alert(user, "data uploaded from buffer")
+ return ITEM_INTERACT_SUCCESS
+
+ balloon_alert(user, "no quantum pad data found!")
+ return NONE
+
+/obj/machinery/quantumpad/attackby(obj/item/weapon, mob/user, params)
+ if(default_deconstruction_screwdriver(user, "qpad-idle-open", "qpad-idle", weapon))
return
- if(panel_open)
- if(I.tool_behaviour == TOOL_MULTITOOL)
- if(!multitool_check_buffer(user, I))
- return
- var/obj/item/multitool/M = I
- M.set_buffer(src)
- balloon_alert(user, "saved to multitool buffer")
- to_chat(user, span_notice("You save the data in [I]'s buffer. It can now be saved to pads with closed panels."))
- return TRUE
- else if(I.tool_behaviour == TOOL_MULTITOOL)
- if(!multitool_check_buffer(user, I))
- return
- var/obj/item/multitool/M = I
- if(istype(M.buffer, /obj/machinery/quantumpad))
- if(M.buffer == src)
- balloon_alert(user, "cannot link to self!")
- return TRUE
- else
- linked_pad = M.buffer
- balloon_alert(user, "data uploaded from buffer")
- return TRUE
- else
- balloon_alert(user, "no quantum pad data found!")
- return TRUE
-
- else if(istype(I, /obj/item/quantum_keycard))
- var/obj/item/quantum_keycard/K = I
+ if(istype(weapon, /obj/item/quantum_keycard))
+ var/obj/item/quantum_keycard/K = weapon
if(K.qpad)
to_chat(user, span_notice("You insert [K] into [src]'s card slot, activating it."))
interact(user, K.qpad)
@@ -93,7 +86,7 @@
to_chat(user, span_notice("You complete the link between [K] and [src]."))
K.set_pad(src)
- if(default_deconstruction_crowbar(I))
+ if(default_deconstruction_crowbar(weapon))
return
return ..()
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index 77e1efbdfa1..fb68631b766 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -246,22 +246,19 @@
/// Returns a multitool from a user depending on their mobtype.
/obj/machinery/telecomms/proc/get_multitool(mob/user)
- var/obj/item/multitool/multitool = null
- // Let's double check
- if(!HAS_SILICON_ACCESS(user) && istype(user.get_active_held_item(), /obj/item/multitool))
- multitool = user.get_active_held_item()
- else if(isAI(user))
+ . = null
+ if(isAI(user))
var/mob/living/silicon/ai/U = user
- multitool = U.aiMulti
- else if(iscyborg(user) && in_range(user, src))
- var/mob/living/silicon/robot/borguser = user
- for(var/obj/item/borg/cyborg_omnitool/toolarm in borguser.held_items)
- if(istype(toolarm.selected, /obj/item/multitool))
- multitool = toolarm.selected
- break
- return multitool
+ return U.aiMulti
-/obj/machinery/telecomms/proc/canAccess(mob/user)
- if(HAS_SILICON_ACCESS(user) || in_range(user, src))
- return TRUE
- return FALSE
+ var/obj/item/held_item = user.get_active_held_item()
+ if(QDELETED(held_item))
+ return
+ held_item = held_item.get_proxy_attacker_for(src, user) //for borgs omni tool
+ if(held_item.tool_behaviour != TOOL_MULTITOOL)
+ return
+
+ if(!HAS_SILICON_ACCESS(user))
+ return held_item
+ if(iscyborg(user) && in_range(user, src))
+ return held_item
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index 23733344917..c46f6b35154 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -162,24 +162,25 @@
teleporter_console = null
return ..()
+/obj/machinery/teleport/station/multitool_act(mob/living/user, obj/item/multitool/tool)
+ . = NONE
+
+ if(panel_open)
+ tool.set_buffer(src)
+ balloon_alert(user, "saved to multitool buffer")
+ return ITEM_INTERACT_SUCCESS
+
+ if(!istype(tool.buffer, /obj/machinery/teleport/station) || tool.buffer == src)
+ return ITEM_INTERACT_BLOCKING
+
+ if(linked_stations.len < efficiency)
+ linked_stations.Add(tool.buffer)
+ tool.set_buffer(null)
+ balloon_alert(user, "data uploaded from buffer")
+ return ITEM_INTERACT_SUCCESS
+
/obj/machinery/teleport/station/attackby(obj/item/W, mob/user, params)
- if(W.tool_behaviour == TOOL_MULTITOOL)
- if(!multitool_check_buffer(user, W))
- return
- var/obj/item/multitool/M = W
- if(panel_open)
- M.set_buffer(src)
- balloon_alert(user, "saved to multitool buffer")
- else
- if(M.buffer && istype(M.buffer, /obj/machinery/teleport/station) && M.buffer != src)
- if(linked_stations.len < efficiency)
- linked_stations.Add(M.buffer)
- M.set_buffer(null)
- balloon_alert(user, "data uploaded from buffer")
- else
- to_chat(user, span_alert("This station can't hold more information, try to use better parts."))
- return
- else if(default_deconstruction_screwdriver(user, "controller-o", "controller", W))
+ if(default_deconstruction_screwdriver(user, "controller-o", "controller", W))
update_appearance()
return
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 1cdeaa89baf..18fed35de45 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -1732,3 +1732,17 @@
if(!isnull(loc))
SEND_SIGNAL(loc, COMSIG_ATOM_CONTENTS_WEIGHT_CLASS_CHANGED, src, old_w_class, new_w_class)
return TRUE
+
+
+/**
+ * Returns the atom(either itself or an internal module) that will interact/attack the target on behalf of us
+ * For example an object can have different `tool_behaviours` (e.g borg omni tool) but will return an internal reference of that tool to attack for us
+ * You can use it for general purpose polymorphism if you need a proxy atom to interact in a specific way
+ * with a target on behalf on this atom
+ *
+ * Currently used only in the object melee attack chain but can be used anywhere else or even moved up to the atom level if required
+ */
+/obj/item/proc/get_proxy_attacker_for(atom/target, mob/user)
+ RETURN_TYPE(/obj/item)
+
+ return src
diff --git a/code/game/objects/items/botpad_remote.dm b/code/game/objects/items/botpad_remote.dm
index d2f2db3e1ac..6b219725aa0 100644
--- a/code/game/objects/items/botpad_remote.dm
+++ b/code/game/objects/items/botpad_remote.dm
@@ -28,22 +28,23 @@
user?.balloon_alert(user, "no connected pad!")
return
-/obj/item/botpad_remote/multitool_act(mob/living/user, obj/item/tool)
- if(!multitool_check_buffer(user, tool))
+/obj/item/botpad_remote/multitool_act(mob/living/user, obj/item/multitool/multitool)
+ . = NONE
+ if(!istype(multitool.buffer, /obj/machinery/botpad))
return
- var/obj/item/multitool/multitool = tool
- if(istype(multitool.buffer, /obj/machinery/botpad))
- var/obj/machinery/botpad/buffered_remote = multitool.buffer
- if(buffered_remote == connected_botpad)
- to_chat(user, span_warning("Controller cannot connect to its own botpad!"))
- else if(!connected_botpad && istype(buffered_remote, /obj/machinery/botpad))
- connected_botpad = buffered_remote
- connected_botpad.connected_remote = src
- connected_botpad.id = id
- multitool.set_buffer(null)
- to_chat(user, span_notice("You connect the controller to the pad with data from the [multitool.name]'s buffer."))
- else
- to_chat(user, span_warning("Unable to upload!"))
+
+ var/obj/machinery/botpad/buffered_remote = multitool.buffer
+ if(buffered_remote == connected_botpad)
+ to_chat(user, span_warning("Controller cannot connect to its own botpad!"))
+ return ITEM_INTERACT_BLOCKING
+
+ if(!connected_botpad && istype(buffered_remote, /obj/machinery/botpad))
+ connected_botpad = buffered_remote
+ connected_botpad.connected_remote = src
+ connected_botpad.id = id
+ multitool.set_buffer(null)
+ to_chat(user, span_notice("You connect the controller to the pad with data from the [multitool.name]'s buffer."))
+ return ITEM_INTERACT_SUCCESS
/obj/item/botpad_remote/proc/try_launch(mob/living/user)
if(!connected_botpad)
diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm
index 8a4ccff8ced..f16cd084490 100644
--- a/code/game/objects/items/robot/items/tools.dm
+++ b/code/game/objects/items/robot/items/tools.dm
@@ -1,7 +1,5 @@
#define PKBORG_DAMPEN_CYCLE_DELAY (2 SECONDS)
#define POWER_RECHARGE_CYBORG_DRAIN_MULTIPLIER (0.0004 * STANDARD_CELL_RATE)
-#define NO_TOOL "deactivated"
-#define TOOL_DRAPES "surgical_drapes"
/obj/item/cautery/prt //it's a subtype of cauteries so that it inherits the cautery sprites and behavior and stuff, because I'm too lazy to make sprites for this thing
name = "plating repair tool"
@@ -176,71 +174,107 @@
projectile.speed *= (1 / projectile_speed_coefficient)
projectile.cut_overlay(projectile_effect)
-//////////////////////
-///CYBORG OMNITOOLS///
-//////////////////////
+//bare minimum omni-toolset for modularity
+/obj/item/borg/cyborg_omnitool
+ name = "cyborg omni-toolset"
+ desc = "You shouldn't see this in-game normally."
+ icon = 'icons/mob/silicon/robot_items.dmi'
+ icon_state = "toolkit_medborg"
+
+ ///our tools (list of item typepaths)
+ var/list/obj/item/omni_toolkit = list()
+ ///Map of solid objects internally used by the omni tool
+ var/list/obj/item/atoms = list()
+ ///object we are referencing to for force, sharpness and sound
+ var/obj/item/reference
+ //is the toolset upgraded or not
+ var/upgraded = FALSE
+
+/obj/item/borg/cyborg_omnitool/Destroy(force)
+ for(var/obj/item/tool_path as anything in atoms)
+ var/obj/item/tool = atoms[tool_path]
+ if(!QDELETED(tool)) //if we are sharing tools from our other omnitool brothers we don't want to re delete them if they got deleted first
+ qdel(tool)
+ atoms.Cut()
+
+ return ..()
+
+/obj/item/borg/cyborg_omnitool/get_all_tool_behaviours()
+ . = list()
+ for(var/obj/item/tool as anything in omni_toolkit)
+ . += initial(tool.tool_behaviour)
+
+///The omnitool interacts with real world objects based on the state it has assumed
+/obj/item/borg/cyborg_omnitool/get_proxy_attacker_for(atom/target, mob/user)
+ if(!reference)
+ return src
+
+ //first check if we have the tool
+ var/obj/item/tool = atoms[reference]
+ if(!QDELETED(tool))
+ return tool
+
+ //else try to borrow an in-built tool from our other omnitool brothers to save & share memory & such
+ var/mob/living/silicon/robot/borg = user
+ for(var/obj/item/borg/cyborg_omnitool/omni_tool in borg.model.basic_modules)
+ if(omni_tool == src)
+ continue
+ tool = omni_tool.atoms[reference]
+ if(!QDELETED(tool))
+ atoms[reference] = tool
+ return tool
+
+ //if all else fails just make a new one from scratch
+ tool = new reference(user)
+ ADD_TRAIT(tool, TRAIT_NODROP, CYBORG_ITEM_TRAIT)
+ atoms[reference] = tool
+ return tool
+
+/obj/item/borg/cyborg_omnitool/attack_self(mob/user)
+ //build the radial menu options
+ var/list/radial_menu_options = list()
+ for(var/obj/item/tool as anything in omni_toolkit)
+ radial_menu_options[initial(tool.tool_behaviour)] = image(icon = initial(tool.icon), icon_state = initial(tool.icon_state))
+
+ //assign the new tool behaviour
+ var/new_tool_behaviour = show_radial_menu(user, src, radial_menu_options, require_near = TRUE, tooltips = TRUE)
+ if(isnull(new_tool_behaviour) || new_tool_behaviour == tool_behaviour)
+ return
+ tool_behaviour = new_tool_behaviour
+
+ //set the reference & update icons
+ for(var/obj/item/tool as anything in omni_toolkit)
+ if(initial(tool.tool_behaviour) == new_tool_behaviour)
+ reference = tool
+ update_appearance(UPDATE_ICON_STATE)
+ playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE)
+ break
+
+/obj/item/borg/cyborg_omnitool/update_icon_state()
+ icon_state = initial(icon_state)
+
+ if (tool_behaviour)
+ icon_state += "_[sanitize_css_class_name(tool_behaviour)]"
+
+ return ..()
/**
- Onmi Toolboxs act as a cache of tools for a particular borg's omnitools. Not all borg
- get a toolbox (as not all borgs use omnitools), and those that do can only have one
- toolbox. The toolbox keeps track of a borg's omnitool arms, and handles speed upgrades.
+ * Is this omni tool upgraded or not
+ * Arguments
+ *
+ * * upgrade - TRUE/FALSE for upgraded
+ */
+/obj/item/borg/cyborg_omnitool/proc/set_upgraded(upgrade)
+ upgraded = upgraded
- Omnitools are the actual tool arms for the cyborg to interact with. When attack_self
- is called, they can select a tool from the toolbox. The tool is not moved, and instead
- only referenced in place of the omnitool's own attacks. The omnitool also takes on
- the tool's sprite, which completes the illusion. In this way, multiple tools are
- shared between multiple omnitool arms. A multitool's buffer, for example, will not
- depend on which omnitool arm was used to set it.
-*/
-/obj/item/cyborg_omnitoolbox
- name = "broken cyborg toolbox"
- desc = "Some internal part of a broken cyborg."
- icon = 'icons/mob/silicon/robot_items.dmi'
- icon_state = "lollipop"
- toolspeed = 10
- ///List of Omnitool "arms" that the borg has.
- var/list/omnitools = list()
- ///List of paths for tools. These will be created during Initialize()
- var/list/toolpaths = list()
- ///Target Toolspeed to set after reciving an omnitool upgrade
- var/upgraded_toolspeed = 10
- ///Whether we currently have the upgraded speed
- var/currently_upgraded = FALSE
+ playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE)
-/obj/item/cyborg_omnitoolbox/Initialize(mapload)
- . = ..()
- if(!toolpaths.len)
- return
+/obj/item/borg/cyborg_omnitool/medical
+ name = "surgical omni-toolset"
+ desc = "A set of surgical tools used by cyborgs to operate on various surgical operations."
- var/obj/item/newitem
- for(var/newpath in toolpaths)
- newitem = new newpath(src)
- newitem.toolspeed = toolspeed //In case thse have different base speeds as stand-alone tools on other borgs
- ADD_TRAIT(newitem, TRAIT_NODROP, CYBORG_ITEM_TRAIT)
-
-/obj/item/cyborg_omnitoolbox/proc/set_upgrade(upgrade = FALSE)
- for(var/obj/item/tool in contents)
- if(upgrade)
- tool.toolspeed = upgraded_toolspeed
- else
- tool.toolspeed = toolspeed
- currently_upgraded = upgrade
-
-/obj/item/cyborg_omnitoolbox/engineering
- toolspeed = 0.5
- upgraded_toolspeed = 0.3
- toolpaths = list(
- /obj/item/wrench/cyborg,
- /obj/item/wirecutters/cyborg,
- /obj/item/screwdriver/cyborg,
- /obj/item/crowbar/cyborg,
- /obj/item/multitool/cyborg,
- )
-
-/obj/item/cyborg_omnitoolbox/medical
- toolspeed = 1
- upgraded_toolspeed = 0.7
- toolpaths = list(
+ omni_toolkit = list(
+ /obj/item/surgical_drapes/cyborg,
/obj/item/scalpel/cyborg,
/obj/item/surgicaldrill/cyborg,
/obj/item/hemostat/cyborg,
@@ -250,72 +284,28 @@
/obj/item/bonesetter/cyborg,
)
-/obj/item/borg/cyborg_omnitool
- name = "broken cyborg tool arm"
- desc = "Some internal part of a broken cyborg."
- icon = 'icons/mob/silicon/robot_items.dmi'
- icon_state = "lollipop"
- ///Ref to the toolbox, since our own loc will be changing
- var/obj/item/cyborg_omnitoolbox/toolbox
- ///Ref to currently selected tool, if any
- var/obj/item/selected
-
-/obj/item/borg/cyborg_omnitool/Initialize(mapload)
- . = ..()
- if(!iscyborg(loc.loc))
- return
- var/obj/item/robot_model/model = loc
- var/obj/item/cyborg_omnitoolbox/chassis_toolbox = model.toolbox
- if(!chassis_toolbox)
- return
- toolbox = chassis_toolbox
- toolbox.omnitools += src
-
-/obj/item/borg/cyborg_omnitool/attack_self(mob/user)
- var/list/radial_menu_options = list()
- for(var/obj/item/borgtool in toolbox.contents)
- radial_menu_options[borgtool] = image(icon = borgtool.icon, icon_state = borgtool.icon_state)
- var/obj/item/potential_new_tool = show_radial_menu(user, src, radial_menu_options, require_near = TRUE, tooltips = TRUE)
- if(!potential_new_tool)
- return ..()
- if(potential_new_tool == selected)
- return ..()
- for(var/obj/item/borg/cyborg_omnitool/coworker in toolbox.omnitools)
- if(coworker.selected == potential_new_tool)
- coworker.deselect() //Can I borrow that please
- break
- selected = potential_new_tool
- icon_state = selected.icon_state
- playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE)
- return ..()
-
-/obj/item/borg/cyborg_omnitool/proc/deselect()
- if(!selected)
- return
- selected = null
- icon_state = initial(icon_state)
- playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE)
-
-/obj/item/borg/cyborg_omnitool/cyborg_unequip()
- deselect()
- return ..()
-
-/obj/item/borg/cyborg_omnitool/melee_attack_chain(mob/user, atom/target, params)
- if(selected)
- return selected.melee_attack_chain(user, target, params)
- return ..()
-
+//Toolset for engineering cyborgs, this is all of the tools except for the welding tool. since it's quite hard to implement (read:can't be arsed to)
/obj/item/borg/cyborg_omnitool/engineering
name = "engineering omni-toolset"
desc = "A set of engineering tools used by cyborgs to conduct various engineering tasks."
+ icon = 'icons/obj/items_cyborg.dmi'
icon_state = "toolkit_engiborg"
-/obj/item/borg/cyborg_omnitool/medical
- name = "surgical omni-toolset"
- desc = "A set of surgical tools used by cyborgs to operate on various surgical operations."
- icon_state = "toolkit_medborg"
+ omni_toolkit = list(
+ /obj/item/wrench/cyborg,
+ /obj/item/wirecutters/cyborg,
+ /obj/item/screwdriver/cyborg,
+ /obj/item/crowbar/cyborg,
+ /obj/item/multitool/cyborg,
+ )
+
+/obj/item/borg/cyborg_omnitool/engineering/examine(mob/user)
+ . = ..()
+
+ if(tool_behaviour == TOOL_MULTITOOL)
+ for(var/obj/item/multitool/tool in atoms)
+ . += "Its multitool buffer contains [tool.buffer]"
+ break
#undef PKBORG_DAMPEN_CYCLE_DELAY
#undef POWER_RECHARGE_CYBORG_DRAIN_MULTIPLIER
-#undef NO_TOOL
-#undef TOOL_DRAPES
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index b2994028c70..6fa32ae31e2 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -428,18 +428,21 @@
. = ..()
if(!.)
return .
- if(cyborg.model.toolbox.currently_upgraded)
- to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!"))
- return FALSE
- cyborg.model.toolbox.set_upgrade(TRUE)
ADD_TRAIT(cyborg, TRAIT_FASTMED, REF(src))
+ for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules)
+ if(omnitool_upgrade.upgraded)
+ to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!"))
+ return FALSE
+ for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules)
+ omnitool.set_upgraded(TRUE)
/obj/item/borg/upgrade/surgery_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr)
. = ..()
if(!.)
return .
- cyborg.model.toolbox.set_upgrade(FALSE)
REMOVE_TRAIT(cyborg, TRAIT_FASTMED, REF(src))
+ for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules)
+ omnitool.set_upgraded(FALSE)
/obj/item/borg/upgrade/engineering_omnitool
name = "cyborg engineering omni-tool upgrade"
@@ -454,16 +457,19 @@
. = ..()
if(!.)
return .
- if(cyborg.model.toolbox.currently_upgraded)
- to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!"))
- return FALSE
- cyborg.model.toolbox.set_upgrade(TRUE)
+ for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules)
+ if(omnitool_upgrade.upgraded)
+ to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!"))
+ return FALSE
+ for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules)
+ omnitool.set_upgraded(TRUE)
/obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr)
. = ..()
if(!.)
return .
- cyborg.model.toolbox.set_upgrade(FALSE)
+ for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules)
+ omnitool.set_upgraded(FALSE)
/obj/item/borg/upgrade/defib
name = "medical cyborg defibrillator"
diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm
index 12d9deedbae..84b9ac26e9b 100644
--- a/code/game/turfs/open/floor.dm
+++ b/code/game/turfs/open/floor.dm
@@ -142,7 +142,7 @@
/turf/open/floor/proc/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
if(T.turf_type == type && T.turf_dir == dir)
return
- var/obj/item/crowbar/CB = user.is_holding_item_of_type(/obj/item/crowbar)
+ var/obj/item/crowbar/CB = user.is_holding_tool_quality(TOOL_CROWBAR)
if(!CB)
return
var/turf/open/floor/plating/P = pry_tile(CB, user, TRUE)
diff --git a/code/game/turfs/open/floor/fancy_floor.dm b/code/game/turfs/open/floor/fancy_floor.dm
index 4d79e6b1b31..cfece702af4 100644
--- a/code/game/turfs/open/floor/fancy_floor.dm
+++ b/code/game/turfs/open/floor/fancy_floor.dm
@@ -34,9 +34,9 @@
/turf/open/floor/wood/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
if(T.turf_type == type)
return
- var/obj/item/tool = user.is_holding_item_of_type(/obj/item/screwdriver)
+ var/obj/item/tool = user.is_holding_tool_quality(TOOL_SCREWDRIVER)
if(!tool)
- tool = user.is_holding_item_of_type(/obj/item/crowbar)
+ tool = user.is_holding_tool_quality(TOOL_CROWBAR)
if(!tool)
return
var/turf/open/floor/plating/P = pry_tile(tool, user, TRUE)
diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm
index a52107ce8b2..385afb0f81f 100644
--- a/code/modules/mining/machine_stacking.dm
+++ b/code/modules/mining/machine_stacking.dm
@@ -31,13 +31,10 @@
machine = null
return ..()
-/obj/machinery/mineral/stacking_unit_console/multitool_act(mob/living/user, obj/item/I)
- if(!multitool_check_buffer(user, I))
- return
- var/obj/item/multitool/M = I
+/obj/machinery/mineral/stacking_unit_console/multitool_act(mob/living/user, obj/item/multitool/M)
M.set_buffer(src)
balloon_alert(user, "saved to multitool buffer")
- return TRUE
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/mineral/stacking_unit_console/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm
index 4fc4bd5d8c1..1721d6ec2c1 100644
--- a/code/modules/mob/living/silicon/robot/robot_model.dm
+++ b/code/modules/mob/living/silicon/robot/robot_model.dm
@@ -53,17 +53,9 @@
var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3)
///List of skins the borg can be reskinned to, optional
var/list/borg_skins
- ///Omnitoolbox, holder of certain borg tools. Not all models have one
- var/obj/item/cyborg_omnitoolbox/toolbox
- ///Path to toolbox, if a model gets one
- var/toolbox_path
/obj/item/robot_model/Initialize(mapload)
. = ..()
-
- if(toolbox_path)
- toolbox = new toolbox_path(src)
-
for(var/path in basic_modules)
var/obj/item/new_module = new path(src)
basic_modules += new_module
@@ -406,7 +398,6 @@
model_select_icon = "engineer"
model_traits = list(TRAIT_NEGATES_GRAVITY)
hat_offset = -4
- toolbox_path = /obj/item/cyborg_omnitoolbox/engineering
/obj/item/robot_model/janitor
name = "Janitor"
@@ -687,7 +678,6 @@
/obj/item/reagent_containers/syringe,
/obj/item/borg/cyborg_omnitool/medical,
/obj/item/borg/cyborg_omnitool/medical,
- /obj/item/surgical_drapes/cyborg,
/obj/item/blood_filter,
/obj/item/extinguisher/mini,
/obj/item/emergency_bed/silicon,
@@ -705,7 +695,6 @@
model_select_icon = "medical"
model_traits = list(TRAIT_PUSHIMMUNE)
hat_offset = 3
- toolbox_path = /obj/item/cyborg_omnitoolbox/medical
borg_skins = list(
"Machinified Doctor" = list(SKIN_ICON_STATE = "medical"),
"Qualified Doctor" = list(SKIN_ICON_STATE = "qualified_doctor"),
@@ -888,7 +877,6 @@
/obj/item/healthanalyzer,
/obj/item/borg/cyborg_omnitool/medical,
/obj/item/borg/cyborg_omnitool/medical,
- /obj/item/surgical_drapes/cyborg,
/obj/item/blood_filter,
/obj/item/melee/energy/sword/cyborg/saw,
/obj/item/emergency_bed/silicon,
@@ -904,7 +892,6 @@
model_select_icon = "malf"
model_traits = list(TRAIT_PUSHIMMUNE)
hat_offset = 3
- toolbox_path = /obj/item/cyborg_omnitoolbox/medical
/obj/item/robot_model/saboteur
name = "Syndicate Saboteur"
@@ -934,7 +921,6 @@
model_select_icon = "malf"
model_traits = list(TRAIT_PUSHIMMUNE, TRAIT_NEGATES_GRAVITY)
hat_offset = -4
- toolbox_path = /obj/item/cyborg_omnitoolbox/engineering
canDispose = TRUE
/obj/item/robot_model/syndicate/kiltborg
diff --git a/code/modules/mod/mod_link.dm b/code/modules/mod/mod_link.dm
index 5733d48f45f..ad7addf691b 100644
--- a/code/modules/mod/mod_link.dm
+++ b/code/modules/mod/mod_link.dm
@@ -77,29 +77,34 @@
)
/obj/item/mod/control/multitool_act_secondary(mob/living/user, obj/item/multitool/tool)
- if(!multitool_check_buffer(user, tool))
- return
+ . = NONE
+
var/tool_frequency = null
if(istype(tool.buffer, /datum/mod_link))
var/datum/mod_link/buffer_link = tool.buffer
tool_frequency = buffer_link.frequency
balloon_alert(user, "frequency set")
+ . = ITEM_INTERACT_SUCCESS
if(!tool_frequency && mod_link.frequency)
tool.set_buffer(mod_link)
balloon_alert(user, "frequency copied")
+ . = ITEM_INTERACT_SUCCESS
else if(tool_frequency && !mod_link.frequency)
mod_link.frequency = tool_frequency
+ . = ITEM_INTERACT_SUCCESS
else if(tool_frequency && mod_link.frequency)
var/response = tgui_alert(user, "Would you like to copy or imprint the frequency?", "MODlink Frequency", list("Copy", "Imprint"))
if(!user.is_holding(tool))
- return
+ return ITEM_INTERACT_BLOCKING
switch(response)
if("Copy")
tool.set_buffer(mod_link)
balloon_alert(user, "frequency copied")
+ . = ITEM_INTERACT_SUCCESS
if("Imprint")
mod_link.frequency = tool_frequency
balloon_alert(user, "frequency set")
+ . = ITEM_INTERACT_SUCCESS
/obj/item/mod/control/proc/can_call()
return get_charge() && wearer && wearer.stat < DEAD
@@ -227,29 +232,34 @@
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
/obj/item/clothing/neck/link_scryer/multitool_act_secondary(mob/living/user, obj/item/multitool/tool)
- if(!multitool_check_buffer(user, tool))
- return
+ . = NONE
+
var/tool_frequency = null
if(istype(tool.buffer, /datum/mod_link))
var/datum/mod_link/buffer_link = tool.buffer
tool_frequency = buffer_link.frequency
balloon_alert(user, "frequency set")
+ . = ITEM_INTERACT_SUCCESS
if(!tool_frequency && mod_link.frequency)
tool.set_buffer(mod_link)
balloon_alert(user, "frequency copied")
+ . = ITEM_INTERACT_SUCCESS
else if(tool_frequency && !mod_link.frequency)
mod_link.frequency = tool_frequency
+ . = ITEM_INTERACT_SUCCESS
else if(tool_frequency && mod_link.frequency)
var/response = tgui_alert(user, "Would you like to copy or imprint the frequency?", "MODlink Frequency", list("Copy", "Imprint"))
if(!user.is_holding(tool))
- return
+ return ITEM_INTERACT_BLOCKING
switch(response)
if("Copy")
tool.set_buffer(mod_link)
balloon_alert(user, "frequency copied")
+ . = ITEM_INTERACT_SUCCESS
if("Imprint")
mod_link.frequency = tool_frequency
balloon_alert(user, "frequency set")
+ . = ITEM_INTERACT_SUCCESS
/obj/item/clothing/neck/link_scryer/worn_overlays(mutable_appearance/standing, isinhands)
. = ..()
diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm
index 5c849f4a530..b4e97615a92 100644
--- a/code/modules/paperwork/ticketmachine.dm
+++ b/code/modules/paperwork/ticketmachine.dm
@@ -49,13 +49,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/ticket_machine, 32)
. += span_notice("The ticket machine shows that ticket #[current_number] is currently being served.")
. += span_notice("You can take a ticket out with Left-Click to be number [ticket_number + 1] in queue.")
-/obj/machinery/ticket_machine/multitool_act(mob/living/user, obj/item/I)
- if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
- return
- var/obj/item/multitool/M = I
+/obj/machinery/ticket_machine/multitool_act(mob/living/user, obj/item/multitool/M)
M.set_buffer(src)
balloon_alert(user, "saved to multitool buffer")
- return TRUE
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/ticket_machine/emag_act(mob/user, obj/item/card/emag/emag_card) //Emag the ticket machine to dispense burning tickets, as well as randomize its number to destroy the HoP's mind.
if(obj_flags & EMAGGED)
diff --git a/code/modules/plumbing/plumbers/teleporter.dm b/code/modules/plumbing/plumbers/teleporter.dm
index df79220d15a..46c46d594f6 100644
--- a/code/modules/plumbing/plumbers/teleporter.dm
+++ b/code/modules/plumbing/plumbers/teleporter.dm
@@ -12,15 +12,10 @@
. = ..()
AddComponent(/datum/component/plumbing/simple_demand, bolt, layer)
-/obj/machinery/plumbing/sender/multitool_act(mob/living/user, obj/item/I)
- if(!multitool_check_buffer(user, I))
- return
-
- var/obj/item/multitool/M = I
-
+/obj/machinery/plumbing/sender/multitool_act(mob/living/user, obj/item/multitool/M)
if(!istype(M.buffer, /obj/machinery/plumbing/receiver))
to_chat(user, span_warning("Invalid buffer."))
- return
+ return ITEM_INTERACT_BLOCKING
if(target)
lose_teleport_target()
@@ -28,7 +23,7 @@
set_teleport_target(M.buffer)
to_chat(user, span_green("You succesfully link [src] to the [M.buffer]."))
- return TRUE
+ return ITEM_INTERACT_SUCCESS
///Lose our previous target and make our previous target lose us. Seperate proc because I feel like I'll need this again
/obj/machinery/plumbing/sender/proc/lose_teleport_target()
@@ -67,14 +62,10 @@
. = ..()
AddComponent(/datum/component/plumbing/simple_supply, bolt)
-/obj/machinery/plumbing/receiver/multitool_act(mob/living/user, obj/item/I)
- if(!multitool_check_buffer(user, I))
- return
-
- var/obj/item/multitool/M = I
+/obj/machinery/plumbing/receiver/multitool_act(mob/living/user, obj/item/multitool/M)
M.set_buffer(src)
balloon_alert(user, "saved to multitool buffer")
- return TRUE
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/plumbing/receiver/process(seconds_per_tick)
if(!is_operational || panel_open)
diff --git a/code/modules/recycling/disposal/construction.dm b/code/modules/recycling/disposal/construction.dm
index 903a59a9305..13f43b1f4a4 100644
--- a/code/modules/recycling/disposal/construction.dm
+++ b/code/modules/recycling/disposal/construction.dm
@@ -109,7 +109,7 @@
var/turf/T = get_turf(src)
if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && isfloorturf(T))
- var/obj/item/crowbar/held_crowbar = user.is_holding_item_of_type(/obj/item/crowbar)
+ var/obj/item/crowbar/held_crowbar = user.is_holding_tool_quality(TOOL_CROWBAR)
if(!held_crowbar || !T.crowbar_act(user, held_crowbar))
to_chat(user, span_warning("You can only attach the [pipename] if the floor plating is removed!"))
return TRUE
diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm
index 069447c6f45..0cfca236d24 100644
--- a/code/modules/research/rdmachines.dm
+++ b/code/modules/research/rdmachines.dm
@@ -72,7 +72,7 @@
return CONTEXTUAL_SCREENTIP_SET
else
if(held_item.tool_behaviour == TOOL_MULTITOOL)
- var/obj/item/multitool/tool = held_item
+ var/obj/item/multitool/tool = held_item.get_proxy_attacker_for(src, user)
if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb))
context[SCREENTIP_CONTEXT_LMB] = "Upload Techweb"
context[SCREENTIP_CONTEXT_RMB] = "Upload Techweb"
diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm
index c83f710d1df..e2feaa2bc26 100644
--- a/code/modules/station_goals/bsa.dm
+++ b/code/modules/station_goals/bsa.dm
@@ -50,13 +50,10 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE)
. = ..()
AddComponent(/datum/component/simple_rotation)
-/obj/machinery/bsa/back/multitool_act(mob/living/user, obj/item/I)
- if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
- return
- var/obj/item/multitool/M = I
+/obj/machinery/bsa/back/multitool_act(mob/living/user, obj/item/multitool/M)
M.set_buffer(src)
balloon_alert(user, "saved to multitool buffer")
- return TRUE
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/bsa/front
name = "Bluespace Artillery Bore"
@@ -67,13 +64,10 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE)
. = ..()
AddComponent(/datum/component/simple_rotation)
-/obj/machinery/bsa/front/multitool_act(mob/living/user, obj/item/I)
- if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
- return
- var/obj/item/multitool/M = I
+/obj/machinery/bsa/front/multitool_act(mob/living/user, obj/item/multitool/M)
M.set_buffer(src)
balloon_alert(user, "saved to multitool buffer")
- return TRUE
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/bsa/middle
name = "Bluespace Artillery Fusor"
@@ -86,22 +80,19 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE)
. = ..()
AddComponent(/datum/component/simple_rotation)
-/obj/machinery/bsa/middle/multitool_act(mob/living/user, obj/item/I)
- if(!multitool_check_buffer(user, I))
- return
- var/obj/item/multitool/M = I
- if(M.buffer)
- if(istype(M.buffer, /obj/machinery/bsa/back))
- back_ref = WEAKREF(M.buffer)
- to_chat(user, span_notice("You link [src] with [M.buffer]."))
- M.set_buffer(null)
- else if(istype(M.buffer, /obj/machinery/bsa/front))
- front_ref = WEAKREF(M.buffer)
- to_chat(user, span_notice("You link [src] with [M.buffer]."))
- M.set_buffer(null)
- else
- to_chat(user, span_warning("[I]'s data buffer is empty!"))
- return TRUE
+/obj/machinery/bsa/middle/multitool_act(mob/living/user, obj/item/multitool/tool)
+ . = NONE
+
+ if(istype(tool.buffer, /obj/machinery/bsa/back))
+ back_ref = WEAKREF(tool.buffer)
+ to_chat(user, span_notice("You link [src] with [tool.buffer]."))
+ tool.set_buffer(null)
+ return ITEM_INTERACT_SUCCESS
+ else if(istype(tool.buffer, /obj/machinery/bsa/front))
+ front_ref = WEAKREF(tool.buffer)
+ to_chat(user, span_notice("You link [src] with [tool.buffer]."))
+ tool.set_buffer(null)
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/bsa/middle/proc/check_completion()
var/obj/machinery/bsa/front/front = front_ref?.resolve()
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index 17444590cf2..a555548e432 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -124,10 +124,6 @@
if(isnull(step))
return FALSE
var/obj/item/tool = user.get_active_held_item()
- if(istype(tool, /obj/item/borg/cyborg_omnitool)) //catches borg surgeries
- var/obj/item/borg/cyborg_omnitool/toolarm = tool
- if(toolarm.selected)
- tool = toolarm.selected
if(step.try_op(user, target, user.zone_selected, tool, src, try_to_fail))
return TRUE
if(tool && tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index 6c3ee9c0147..eba496e0b8c 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -316,6 +316,7 @@
attack_verb_continuous = list("slaps")
attack_verb_simple = list("slap")
interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_IGNORE_MOBILITY
+ tool_behaviour = TOOL_DRAPES
/obj/item/surgical_drapes/Initialize(mapload)
. = ..()
diff --git a/code/modules/unit_tests/cyborg_tool.dm b/code/modules/unit_tests/cyborg_tool.dm
index 711f0948aee..39aed619ec5 100644
--- a/code/modules/unit_tests/cyborg_tool.dm
+++ b/code/modules/unit_tests/cyborg_tool.dm
@@ -5,7 +5,7 @@
/datum/unit_test/cyborg_tool/Run()
var/mob/living/carbon/human/consistent/not_a_borg = allocate(__IMPLIED_TYPE__)
var/obj/item/borg/cyborg_omnitool/engineering/tool = allocate(__IMPLIED_TYPE__)
- tool.selected = allocate(/obj/item/wrench/cyborg)
+ tool.tool_behaviour = TOOL_WRENCH
not_a_borg.put_in_active_hand(tool)