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
🆑
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
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
This commit is contained in:
SyncIt21
2024-07-04 04:17:18 +05:30
committed by GitHub
parent 6fa8c95c9c
commit e4c5c2fc2a
32 changed files with 353 additions and 394 deletions
+1
View File
@@ -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"
+5
View File
@@ -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)
@@ -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]!"))
+4 -15
View File
@@ -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
-8
View File
@@ -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
+2 -5
View File
@@ -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)
@@ -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]
+25 -21
View File
@@ -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
+9 -8
View File
@@ -66,6 +66,15 @@
if(in_range(user, src) || isobserver(user))
. += span_notice("The status display reads: Maximum range: <b>[range]</b> 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
+4 -5
View File
@@ -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)
@@ -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)
@@ -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)
+23 -30
View File
@@ -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 ..()
@@ -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
+18 -17
View File
@@ -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
+14
View File
@@ -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
+16 -15
View File
@@ -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)
+113 -123
View File
@@ -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
+16 -10
View File
@@ -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"
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -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)
+2 -5
View File
@@ -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)
@@ -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
+16 -6
View File
@@ -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)
. = ..()
+2 -5
View File
@@ -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 <b>Left-Click</b> 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)
+5 -14
View File
@@ -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)
@@ -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
+1 -1
View File
@@ -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"
+17 -26
View File
@@ -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()
-4
View File
@@ -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
+1
View File
@@ -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)
. = ..()
+1 -1
View File
@@ -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)