From e4c5c2fc2a3eca71e971d16ec73cd449794c67ac Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Thu, 4 Jul 2024 04:17:18 +0530 Subject: [PATCH] Allows for proxy atoms in object melee attack chain (#83860) ## About The Pull Request 1. Objects now have an `get_proxy_for()` proc. This returns an atom that will participate in the object melee attack chain on behalf of your atom. Allows for general purpose polymorphism per object interaction 2. Cleaned up some multitool acts to accommodate proxy behaviour 3. You can pry tiles as an Engiborg with crowbar in hand & do other similar behaviour with crowbar 5. Improves & Depends on #83880. We don't need a hidden omni toolbox & can create the tools directly in the omnitool and pass them in the attack chain as a proxy rather than calling the attack chain manually. All tools are on the borg directly - Fixes #84355 - Fixes #84359 - Fixes #84393 ## Changelog SyncIt21,zxaber :cl: fix: omni crowbar tool interaction for replacing tiles has been fixed fix: techfab screentip does not runtime when you hover over it with an omnitool multitool fix: medi borgs can do brain surgery again code: improved multitool & general tool code for some machines /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/__DEFINES/tools.dm | 1 + code/_onclick/item_attack.dm | 5 + .../components/material/remote_materials.dm | 6 +- code/datums/components/surgery_initiator.dm | 19 +- code/game/atom/atom_tool_acts.dm | 8 - code/game/machinery/botlaunchpad.dm | 7 +- .../machinery/computer/launchpad_control.dm | 24 +- code/game/machinery/computer/mechlaunchpad.dm | 46 ++-- code/game/machinery/launch_pad.dm | 17 +- code/game/machinery/mechlaunchpad.dm | 9 +- .../machinery/porta_turret/portable_turret.dm | 34 +-- .../porta_turret/portable_turret_cover.dm | 16 +- code/game/machinery/quantum_pad.dm | 53 ++-- .../telecomms/machine_interactions.dm | 31 ++- code/game/machinery/teleporter.dm | 35 +-- code/game/objects/items.dm | 14 ++ code/game/objects/items/botpad_remote.dm | 31 +-- code/game/objects/items/robot/items/tools.dm | 236 +++++++++--------- .../objects/items/robot/robot_upgrades.dm | 26 +- code/game/turfs/open/floor.dm | 2 +- code/game/turfs/open/floor/fancy_floor.dm | 4 +- code/modules/mining/machine_stacking.dm | 7 +- .../mob/living/silicon/robot/robot_model.dm | 14 -- code/modules/mod/mod_link.dm | 22 +- code/modules/paperwork/ticketmachine.dm | 7 +- code/modules/plumbing/plumbers/teleporter.dm | 19 +- .../recycling/disposal/construction.dm | 2 +- code/modules/research/rdmachines.dm | 2 +- code/modules/station_goals/bsa.dm | 43 ++-- code/modules/surgery/surgery.dm | 4 - code/modules/surgery/tools.dm | 1 + code/modules/unit_tests/cyborg_tool.dm | 2 +- 32 files changed, 353 insertions(+), 394 deletions(-) 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)