From b3c74dca2d8aac1969314687894c43bff15a3608 Mon Sep 17 00:00:00 2001
From: Leland Kemble <70413276+lelandkemble@users.noreply.github.com>
Date: Thu, 2 Jul 2026 00:10:46 -0400
Subject: [PATCH] Moves a plethora of things from attackby() to
item_interaction() (#96726)
## About The Pull Request
50 files. Sorry about that, I was faster today. Just merge without
looking, it'll be fine.
This is the end of `/machinery/` & `/stack/` `attackby()`s(that aren't
actually meant for being attacked) when these are all merged.
Like, 200 left? I think?
Also, this one will make light replacer reloading slightly more
difficult until whichever one converted the light replacer is merged.
If, for some ungodly reason, this one gets merged first.
Changes beyond conversion:
if a `/porta_turret_construct` somehow became anchored out of sync with
its construction steps, it's no longer softlocked
you can no longer place an infinite amount of blackboxes into the
blackbox recorder
a TTV will no longer keep its ghost on your back when you cut its wires
while wearing it
RCLs will properly update their appearance when initially given their
first coil
The creator of `robot_suit/attackby()` has been cursed to spend a
thousand years in the lake of fire
## Why It's Good For The Game
Now that all of these are remade, you can find bugs in them and then get
GBP for fixing them(not that my code would ever have bugs).
## Changelog
:cl:
fix: It's no longer possible to softlock building a turret(if it ever
was)
fix: you can no longer stuff the blackbox recorder full with as many
blackboxes as you've somehow collected
fix: TTVs will no longer remain on your back as a ghost when you cut
their wire straps
fix: RCLs will now properly update their appearance when given their
first coil of cleaners
code: 50 files have been converted from attackby() to item_interaction()
/:cl:
---
.../newscaster/newscaster_machine.dm | 18 +-
code/game/machinery/pipe/pipe_dispenser.dm | 13 +-
.../porta_turret/portable_turret_construct.dm | 271 ++++++------
.../machinery/porta_turret/turret_control.dm | 29 +-
.../machinery/telecomms/machines/allinone.dm | 6 +-
.../telecomms/machines/message_server.dm | 27 +-
.../objects/effects/decals/cleanable/fuel.dm | 11 +-
code/game/objects/effects/portals.dm | 9 +-
.../objects/effects/poster_demotivational.dm | 5 +-
.../objects/effects/poster_motivational.dm | 14 +-
code/game/objects/items/cigarettes.dm | 29 +-
.../circuitboards/computer_circuitboards.dm | 26 +-
code/game/objects/items/courtroom.dm | 14 +-
code/game/objects/items/crab17.dm | 19 +-
.../objects/items/devices/laserpointer.dm | 76 ++--
.../objects/items/devices/pressureplates.dm | 24 +-
.../items/devices/radio/electropack.dm | 35 +-
code/game/objects/items/devices/swapper.dm | 32 +-
.../objects/items/devices/taperecorder.dm | 19 +-
.../objects/items/devices/traitordevices.dm | 38 +-
.../objects/items/devices/transfer_valve.dm | 45 +-
code/game/objects/items/grenades/festive.dm | 28 +-
.../game/objects/items/grenades/ghettobomb.dm | 67 +--
.../game/objects/items/implants/implantpad.dm | 13 +-
.../objects/items/kirby_plants/kirbyplants.dm | 26 +-
code/game/objects/items/latexballoon.dm | 17 +-
code/game/objects/items/mail.dm | 19 +-
code/game/objects/items/piggy_bank.dm | 23 +-
code/game/objects/items/pillow.dm | 34 +-
code/game/objects/items/plushes.dm | 78 ++--
code/game/objects/items/rcd/RCL.dm | 46 ++-
code/game/objects/items/rcd/RSF.dm | 34 +-
code/game/objects/items/rcd/RWD.dm | 11 +-
.../game/objects/items/robot/items/storage.dm | 10 +-
code/game/objects/items/robot/robot_parts.dm | 388 +++++++++---------
code/game/objects/items/sharpener.dm | 49 +--
.../game/objects/items/stacks/sheets/glass.dm | 91 ++--
.../objects/items/stacks/sheets/leather.dm | 20 +-
.../game/objects/items/stacks/sheets/light.dm | 25 +-
.../objects/items/stacks/sheets/mineral.dm | 77 ++--
.../items/stacks/sheets/sheet_types.dm | 31 +-
code/game/objects/items/stacks/stack.dm | 15 +-
code/game/objects/items/stacks/tiles/light.dm | 17 +-
.../items/stacks/tiles/tile_mineral.dm | 41 +-
code/game/objects/items/tail_pin.dm | 13 +-
code/game/objects/items/tanks/tank_types.dm | 22 +-
code/game/objects/items/tanks/tanks.dm | 16 +-
code/game/objects/items/toy_mechs.dm | 12 +-
code/game/objects/items/toys.dm | 144 +++----
code/game/objects/items/wind_turbine.dm | 36 +-
50 files changed, 1134 insertions(+), 1029 deletions(-)
diff --git a/code/game/machinery/newscaster/newscaster_machine.dm b/code/game/machinery/newscaster/newscaster_machine.dm
index 2c1e548f80a..92ff8502ef7 100644
--- a/code/game/machinery/newscaster/newscaster_machine.dm
+++ b/code/game/machinery/newscaster/newscaster_machine.dm
@@ -490,15 +490,15 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
. = ..()
update_appearance()
-/obj/machinery/newscaster/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
- if(istype(attacking_item, /obj/item/paper))
- if(!user.temporarilyRemoveItemFromInventory(attacking_item))
- return
- paper_remaining++
- to_chat(user, span_notice("You insert [attacking_item] into [src]! It now holds [paper_remaining] sheet\s of paper."))
- qdel(attacking_item)
- return
- return ..()
+/obj/machinery/newscaster/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/paper))
+ return NONE
+ if(!user.temporarilyRemoveItemFromInventory(tool))
+ return ITEM_INTERACT_BLOCKING
+ paper_remaining++
+ to_chat(user, span_notice("You insert [tool] into [src]! It now holds [paper_remaining] sheet\s of paper."))
+ qdel(tool)
+ return ITEM_INTERACT_SUCCESS
///returns (machine_stat & broken)
/obj/machinery/newscaster/proc/needs_repair()
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 7c8e0b642b4..0fafff15822 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -151,14 +151,13 @@
ui = new(user, src, "PipeDispenser", name)
ui.open()
-/obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
+/obj/machinery/pipedispenser/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
add_fingerprint(user)
- if (istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter))
- to_chat(usr, span_notice("You put [W] back into [src]."))
- qdel(W)
- return
- else
- return ..()
+ if (!istype(tool, /obj/item/pipe) && !istype(tool, /obj/item/pipe_meter))
+ return NONE
+ to_chat(usr, span_notice("You put [tool] back into [src]."))
+ qdel(tool)
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/pipedispenser/proc/verify_recipe(recipes, path)
for(var/category in recipes)
diff --git a/code/game/machinery/porta_turret/portable_turret_construct.dm b/code/game/machinery/porta_turret/portable_turret_construct.dm
index 6b06894e010..4305dbb936c 100644
--- a/code/game/machinery/porta_turret/portable_turret_construct.dm
+++ b/code/game/machinery/porta_turret/portable_turret_construct.dm
@@ -42,157 +42,162 @@
if(PTURRET_START_EXTERNAL_ARMOUR)
. += span_notice("The turret's armor needs to be welded in place, the armor looks like it could be pried off.")
-/obj/machinery/porta_turret_construct/attackby(obj/item/used, mob/user, list/modifiers, list/attack_modifiers)
+/obj/machinery/porta_turret_construct/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
//this is a bit unwieldy but self-explanatory
switch(build_step)
- if(PTURRET_UNSECURED) //first step
- if(used.tool_behaviour == TOOL_WRENCH && !anchored)
- used.play_tool_sound(src, 100)
- to_chat(user, span_notice("You secure the external bolts."))
- set_anchored(TRUE)
- build_step = PTURRET_BOLTED
- return
-
- else if(used.tool_behaviour == TOOL_CROWBAR && !anchored)
- used.play_tool_sound(src, 75)
- to_chat(user, span_notice("You dismantle the turret construction."))
- new /obj/item/stack/sheet/iron(loc, 5)
- qdel(src)
- return
-
if(PTURRET_BOLTED)
- if(istype(used, /obj/item/stack/sheet/iron))
- var/obj/item/stack/sheet/iron/sheet = used
- if(sheet.use(2))
- to_chat(user, span_notice("You add some metal armor to the interior frame."))
- build_step = PTURRET_START_INTERNAL_ARMOUR
- icon_state = "turret_frame2"
- else
- to_chat(user, span_warning("You need two sheets of iron to continue construction!"))
- return
-
- else if(used.tool_behaviour == TOOL_WRENCH)
- used.play_tool_sound(src, 75)
- to_chat(user, span_notice("You unfasten the external bolts."))
- set_anchored(FALSE)
- build_step = PTURRET_UNSECURED
- return
-
-
- if(PTURRET_START_INTERNAL_ARMOUR)
- if(used.tool_behaviour == TOOL_WRENCH)
- used.play_tool_sound(src, 100)
- to_chat(user, span_notice("You bolt the metal armor into place."))
- build_step = PTURRET_INTERNAL_ARMOUR_ON
- return
-
- else if(used.tool_behaviour == TOOL_WELDER)
- if(!used.tool_start_check(user, amount = 5)) //uses up 5 fuel
- return
-
- to_chat(user, span_notice("You start to remove the turret's interior metal armor..."))
-
- if(used.use_tool(src, user, 20, volume = 50, amount = 5)) //uses up 5 fuel
- build_step = PTURRET_BOLTED
- to_chat(user, span_notice("You remove the turret's interior metal armor."))
- new /obj/item/stack/sheet/iron(drop_location(), 2)
- return
-
+ if(!istype(tool, /obj/item/stack/sheet/iron))
+ return NONE
+ var/obj/item/stack/sheet/iron/sheet = tool
+ if(!sheet.use(2))
+ to_chat(user, span_warning("You need two sheets of iron to continue construction!"))
+ return ITEM_INTERACT_BLOCKING
+ to_chat(user, span_notice("You add some metal armor to the interior frame."))
+ build_step = PTURRET_START_INTERNAL_ARMOUR
+ icon_state = "turret_frame2"
+ return ITEM_INTERACT_SUCCESS
if(PTURRET_INTERNAL_ARMOUR_ON)
- if(istype(used, /obj/item/gun/energy)) //the gun installation part
- var/obj/item/gun/energy/egun = used
- if(egun.gun_flags & TURRET_INCOMPATIBLE)
- to_chat(user, span_notice("You don't think it would be right to add [used] to the turret"))
- return
- if(!user.transferItemToLoc(egun, src))
- return
- installed_gun = egun
- to_chat(user, span_notice("You add [used] to the turret."))
- build_step = PTURRET_GUN_EQUIPPED
- return
- else if(used.tool_behaviour == TOOL_WRENCH)
- used.play_tool_sound(src, 100)
- to_chat(user, span_notice("You remove the turret's metal armor bolts."))
- build_step = PTURRET_START_INTERNAL_ARMOUR
- return
+ if(!istype(tool, /obj/item/gun/energy)) //the gun installation part
+ return NONE
+ var/obj/item/gun/energy/egun = tool
+ if(egun.gun_flags & TURRET_INCOMPATIBLE)
+ to_chat(user, span_notice("You don't think it would be right to add [tool] to the turret"))
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(egun, src))
+ return ITEM_INTERACT_BLOCKING
+ installed_gun = egun
+ to_chat(user, span_notice("You add [tool] to the turret."))
+ build_step = PTURRET_GUN_EQUIPPED
+ return ITEM_INTERACT_SUCCESS
if(PTURRET_GUN_EQUIPPED)
- if(isprox(used))
- build_step = PTURRET_SENSORS_ON
- if(!user.temporarilyRemoveItemFromInventory(used))
- return
- to_chat(user, span_notice("You add the proximity sensor to the turret."))
- qdel(used)
- return
-
-
- if(PTURRET_SENSORS_ON)
- if(used.tool_behaviour == TOOL_SCREWDRIVER)
- used.play_tool_sound(src, 100)
- build_step = PTURRET_CLOSED
- to_chat(user, span_notice("You close the internal access hatch."))
- return
-
+ if(!isprox(tool))
+ return NONE
+ build_step = PTURRET_SENSORS_ON
+ if(!user.temporarilyRemoveItemFromInventory(tool))
+ return ITEM_INTERACT_BLOCKING
+ to_chat(user, span_notice("You add the proximity sensor to the turret."))
+ qdel(tool)
+ return ITEM_INTERACT_SUCCESS
if(PTURRET_CLOSED)
- if(istype(used, /obj/item/stack/sheet/iron))
- var/obj/item/stack/sheet/iron/sheet = used
- if(sheet.use(2))
- to_chat(user, span_notice("You add some metal armor to the exterior frame."))
- build_step = PTURRET_START_EXTERNAL_ARMOUR
- else
- to_chat(user, span_warning("You need two sheets of iron to continue construction!"))
- return
+ if(!istype(tool, /obj/item/stack/sheet/iron))
+ return NONE
+ var/obj/item/stack/sheet/iron/sheet = tool
+ if(!sheet.use(2))
+ to_chat(user, span_warning("You need two sheets of iron to continue construction!"))
+ return ITEM_INTERACT_BLOCKING
+ to_chat(user, span_notice("You add some metal armor to the exterior frame."))
+ build_step = PTURRET_START_EXTERNAL_ARMOUR
+ return ITEM_INTERACT_SUCCESS
- else if(used.tool_behaviour == TOOL_SCREWDRIVER)
- used.play_tool_sound(src, 100)
- build_step = PTURRET_SENSORS_ON
- to_chat(user, span_notice("You open the internal access hatch."))
- return
+ return NONE
+
+/obj/machinery/porta_turret_construct/wrench_act(mob/living/user, obj/item/tool)
+ switch(build_step)
+ if(PTURRET_UNSECURED)
+ tool.play_tool_sound(src, 100)
+ to_chat(user, span_notice("You secure the external bolts."))
+ set_anchored(TRUE)
+ build_step = PTURRET_BOLTED
+ return ITEM_INTERACT_SUCCESS
+
+ if(PTURRET_BOLTED)
+ tool.play_tool_sound(src, 75)
+ to_chat(user, span_notice("You unfasten the external bolts."))
+ set_anchored(FALSE)
+ build_step = PTURRET_UNSECURED
+ return ITEM_INTERACT_SUCCESS
+
+ if(PTURRET_START_INTERNAL_ARMOUR)
+ tool.play_tool_sound(src, 100)
+ to_chat(user, span_notice("You bolt the metal armor into place."))
+ build_step = PTURRET_INTERNAL_ARMOUR_ON
+ return ITEM_INTERACT_SUCCESS
+
+ if(PTURRET_INTERNAL_ARMOUR_ON)
+ tool.play_tool_sound(src, 100)
+ to_chat(user, span_notice("You remove the turret's metal armor bolts."))
+ build_step = PTURRET_START_INTERNAL_ARMOUR
+ return ITEM_INTERACT_SUCCESS
+
+ return ITEM_INTERACT_SKIP_TO_ATTACK
+
+/obj/machinery/porta_turret_construct/crowbar_act(mob/living/user, obj/item/tool)
+ switch(build_step)
+ if(PTURRET_UNSECURED)
+ tool.play_tool_sound(src, 75)
+ to_chat(user, span_notice("You dismantle the turret construction."))
+ new /obj/item/stack/sheet/iron(loc, 5)
+ qdel(src)
+ return ITEM_INTERACT_SUCCESS
if(PTURRET_START_EXTERNAL_ARMOUR)
- if(used.tool_behaviour == TOOL_WELDER)
- if(!used.tool_start_check(user, amount = 5))
- return
+ tool.play_tool_sound(src, 75)
+ to_chat(user, span_notice("You pry off the turret's exterior armor."))
+ new /obj/item/stack/sheet/iron(loc, 2)
+ build_step = PTURRET_CLOSED
+ return ITEM_INTERACT_SUCCESS
- to_chat(user, span_notice("You begin to weld the turret's armor down..."))
- if(used.use_tool(src, user, 30, volume = 50, amount = 5))
- build_step = PTURRET_EXTERNAL_ARMOUR_ON
- to_chat(user, span_notice("You weld the turret's armor down."))
+ return ITEM_INTERACT_SKIP_TO_ATTACK
- //The final step: create a full turret
+/obj/machinery/porta_turret_construct/welder_act(mob/living/user, obj/item/tool)
+ switch(build_step)
+ if(PTURRET_START_INTERNAL_ARMOUR)
+ if(!tool.tool_start_check(user, amount = 5)) //uses up 5 fuel
+ return ITEM_INTERACT_BLOCKING
- var/obj/machinery/porta_turret/turret
- //fuck lasertag turrets
- if(istype(installed_gun, /obj/item/gun/energy/laser/bluetag) || istype(installed_gun, /obj/item/gun/energy/laser/redtag))
- turret = new/obj/machinery/porta_turret/lasertag(loc)
- else
- turret = new/obj/machinery/porta_turret(loc)
- turret.name = finish_name
- turret.installation = installed_gun.type
- turret.setup(installed_gun)
- turret.locked = FALSE
- qdel(src)
- return
+ to_chat(user, span_notice("You start to remove the turret's interior metal armor..."))
+ if(!tool.use_tool(src, user, 20, volume = 50, amount = 5)) //uses up 5 fuel
+ return ITEM_INTERACT_BLOCKING
+ build_step = PTURRET_BOLTED
+ to_chat(user, span_notice("You remove the turret's interior metal armor."))
+ new /obj/item/stack/sheet/iron(drop_location(), 2)
+ return ITEM_INTERACT_SUCCESS
- else if(used.tool_behaviour == TOOL_CROWBAR)
- used.play_tool_sound(src, 75)
- to_chat(user, span_notice("You pry off the turret's exterior armor."))
- new /obj/item/stack/sheet/iron(loc, 2)
- build_step = PTURRET_CLOSED
- return
+ if(PTURRET_START_EXTERNAL_ARMOUR)
+ if(!tool.tool_start_check(user, amount = 5))
+ return ITEM_INTERACT_BLOCKING
- if(used.get_writing_implement_details()?["interaction_mode"] == MODE_WRITING) //you can rename turrets like bots!
- var/choice = tgui_input_text(user, "Enter a new turret name", "Turret Classification", finish_name, max_length = MAX_NAME_LEN)
- if(!choice)
- return
- if(!user.can_perform_action(src))
- return
+ to_chat(user, span_notice("You begin to weld the turret's armor down..."))
+ if(!tool.use_tool(src, user, 30, volume = 50, amount = 5))
+ return ITEM_INTERACT_BLOCKING
+ build_step = PTURRET_EXTERNAL_ARMOUR_ON
+ to_chat(user, span_notice("You weld the turret's armor down."))
- finish_name = choice
- return
- return ..()
+ //The final step: create a full turret
+
+ var/obj/machinery/porta_turret/turret
+ //fuck lasertag turrets
+ if(istype(installed_gun, /obj/item/gun/energy/laser/bluetag) || istype(installed_gun, /obj/item/gun/energy/laser/redtag))
+ turret = new/obj/machinery/porta_turret/lasertag(loc)
+ else
+ turret = new/obj/machinery/porta_turret(loc)
+ turret.name = finish_name
+ turret.installation = installed_gun.type
+ turret.setup(installed_gun)
+ turret.locked = FALSE
+ qdel(src)
+ return ITEM_INTERACT_SUCCESS
+
+ return ITEM_INTERACT_SKIP_TO_ATTACK
+
+/obj/machinery/porta_turret_construct/screwdriver_act(mob/living/user, obj/item/tool)
+ switch(build_step)
+ if(PTURRET_SENSORS_ON)
+ tool.play_tool_sound(src, 100)
+ build_step = PTURRET_CLOSED
+ to_chat(user, span_notice("You close the internal access hatch."))
+ return ITEM_INTERACT_SUCCESS
+
+ if(PTURRET_CLOSED)
+ tool.play_tool_sound(src, 100)
+ build_step = PTURRET_SENSORS_ON
+ to_chat(user, span_notice("You open the internal access hatch."))
+ return ITEM_INTERACT_SUCCESS
+
+ return ITEM_INTERACT_SKIP_TO_ATTACK
/obj/machinery/porta_turret_construct/nameformat(input, user)
finish_name = input
diff --git a/code/game/machinery/porta_turret/turret_control.dm b/code/game/machinery/porta_turret/turret_control.dm
index c1b436f3dcc..f08f35d477c 100644
--- a/code/game/machinery/porta_turret/turret_control.dm
+++ b/code/game/machinery/porta_turret/turret_control.dm
@@ -91,27 +91,30 @@
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, list/modifiers, list/attack_modifiers)
+/obj/machinery/turretid/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(machine_stat & BROKEN)
- return
+ return NONE
if (issilicon(user))
return attack_hand(user)
- var/id = attacking_item.GetID()
+ var/card = tool.GetID()
- if(isnull(id))
- return
+ if(isnull(card))
+ return NONE
- if (check_access(id))
- if(obj_flags & EMAGGED)
- to_chat(user, span_warning("The turret control is unresponsive!"))
- return
-
- locked = !locked
- to_chat(user, span_notice("You [ locked ? "lock" : "unlock"] the panel."))
- else
+ if(!check_access(card))
to_chat(user, span_alert("Access denied."))
+ return ITEM_INTERACT_BLOCKING
+
+ if(obj_flags & EMAGGED)
+ to_chat(user, span_warning("The turret control is unresponsive!"))
+ return ITEM_INTERACT_BLOCKING
+
+ locked = !locked
+ to_chat(user, span_notice("You [ locked ? "lock" : "unlock"] the panel."))
+ return ITEM_INTERACT_SUCCESS
+
/obj/machinery/turretid/emag_act(mob/user, obj/item/card/emag/emag_card)
if(obj_flags & EMAGGED)
diff --git a/code/game/machinery/telecomms/machines/allinone.dm b/code/game/machinery/telecomms/machines/allinone.dm
index 544832a0327..859f8464785 100644
--- a/code/game/machinery/telecomms/machines/allinone.dm
+++ b/code/game/machinery/telecomms/machines/allinone.dm
@@ -93,6 +93,6 @@
sleep(signal.data["slow"]) // simulate the network lag if necessary
signal.broadcast()
-/obj/machinery/telecomms/allinone/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
- if(attacking_item.tool_behaviour == TOOL_MULTITOOL)
- return attack_hand(user)
+/obj/machinery/telecomms/allinone/multitool_act(mob/living/user, obj/item/tool)
+ attack_hand(user)
+ return ITEM_INTERACT_SUCCESS
diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm
index cb34bf1e813..c22020d644d 100644
--- a/code/game/machinery/telecomms/machines/message_server.dm
+++ b/code/game/machinery/telecomms/machines/message_server.dm
@@ -34,18 +34,21 @@
to_chat(user, span_warning("It seems that the blackbox is missing..."))
return
-/obj/machinery/blackbox_recorder/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
- if(istype(attacking_item, /obj/item/blackbox))
- if(HAS_TRAIT(attacking_item, TRAIT_NODROP) || !user.transferItemToLoc(attacking_item, src))
- to_chat(user, span_warning("[attacking_item] is stuck to your hand!"))
- return
- user.visible_message(span_notice("[user] clicks [attacking_item] into [src]!"), \
- span_notice("You press the device into [src], and it clicks into place. The tapes begin spinning again."))
- playsound(src, 'sound/machines/click.ogg', 50, TRUE)
- stored = attacking_item
- update_appearance()
- return
- return ..()
+/obj/machinery/blackbox_recorder/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/blackbox))
+ return NONE
+ if(stored)
+ to_chat(user, span_warning("There's already a blackbox in \the [src].")) //something's gone wrong to get here, but you know, it could happen
+ return ITEM_INTERACT_BLOCKING
+ if(HAS_TRAIT(tool, TRAIT_NODROP) || !user.transferItemToLoc(tool, src))
+ to_chat(user, span_warning("[tool] is stuck to your hand!"))
+ return ITEM_INTERACT_BLOCKING
+ user.visible_message(span_notice("[user] clicks [tool] into [src]!"), \
+ span_notice("You press the device into [src], and it clicks into place. The tapes begin spinning again."))
+ playsound(src, 'sound/machines/click.ogg', 50, TRUE)
+ stored = tool
+ update_appearance()
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/blackbox_recorder/Destroy()
if(stored)
diff --git a/code/game/objects/effects/decals/cleanable/fuel.dm b/code/game/objects/effects/decals/cleanable/fuel.dm
index a55ff28e10d..6dbd03ac8be 100644
--- a/code/game/objects/effects/decals/cleanable/fuel.dm
+++ b/code/game/objects/effects/decals/cleanable/fuel.dm
@@ -82,11 +82,12 @@
ignite()
log_combat(hit_proj.firer, src, "used [hit_proj] to ignite")
-/obj/effect/decal/cleanable/fuel_pool/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
- if(item.ignition_effect(src, user))
- ignite()
- log_combat(user, src, "used [item] to ignite")
- return ..()
+/obj/effect/decal/cleanable/fuel_pool/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!tool.ignition_effect(src, user))
+ return ..()
+ ignite()
+ log_combat(user, src, "used [tool] to ignite")
+ return ITEM_INTERACT_SUCCESS
/obj/effect/decal/cleanable/fuel_pool/proc/on_entered(datum/source, atom/movable/entered_atom)
SIGNAL_HANDLER
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index f35070bc2c4..b6eb8a6e6c8 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -69,10 +69,11 @@
/obj/effect/portal/newtonian_move(inertia_angle, instant = FALSE, start_delay = 0, drift_force = 0, controlled_cap = null)
return TRUE
-/obj/effect/portal/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(user && Adjacent(user))
- teleport(user)
- return TRUE
+/obj/effect/portal/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!Adjacent(user))
+ return ..()
+ teleport(user)
+ return ITEM_INTERACT_SUCCESS
/obj/effect/portal/CanAllowThrough(atom/movable/mover, border_dir)
. = ..()
diff --git a/code/game/objects/effects/poster_demotivational.dm b/code/game/objects/effects/poster_demotivational.dm
index ef946372dfd..bd6141f38c0 100644
--- a/code/game/objects/effects/poster_demotivational.dm
+++ b/code/game/objects/effects/poster_demotivational.dm
@@ -23,9 +23,8 @@
demoraliser = new(src, 7, TRUE, mood_category)
return ..()
-/obj/structure/sign/poster/traitor/attackby(obj/item/tool, mob/user, list/modifiers, list/attack_modifiers)
- if (tool.tool_behaviour == TOOL_WIRECUTTER)
- QDEL_NULL(demoraliser)
+/obj/structure/sign/poster/traitor/wirecutter_act(mob/living/user, obj/item/tool)
+ QDEL_NULL(demoraliser)
return ..()
/obj/structure/sign/poster/traitor/Destroy()
diff --git a/code/game/objects/effects/poster_motivational.dm b/code/game/objects/effects/poster_motivational.dm
index 702cdfdde8a..925f44ae5b9 100644
--- a/code/game/objects/effects/poster_motivational.dm
+++ b/code/game/objects/effects/poster_motivational.dm
@@ -17,17 +17,18 @@
department_grab.quirk_poster_department = quirk_poster_department
/// You can use any spraypaint can on a quirk poster to turn it into a contraband poster from the traitor objective
-/obj/item/poster/quirk/attackby(obj/item/postertool, mob/user, list/modifiers, list/attack_modifiers)
- if(!user.is_antag() || !HAS_TRAIT(user, TRAIT_POSTERBOY) || !istype(postertool, /obj/item/toy/crayon))
- return ..()
+/obj/item/poster/quirk/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!user.is_antag() || !HAS_TRAIT(user, TRAIT_POSTERBOY) || !istype(tool, /obj/item/toy/crayon))
+ return NONE
balloon_alert(user, "converting poster...")
if(!do_after(user, 5 SECONDS, user))
balloon_alert(user, "interrupted!")
- return
+ return ITEM_INTERACT_BLOCKING
var/obj/item/poster/traitor/quirkspawn = new(get_turf(src))
user.put_in_hands(quirkspawn)
to_chat(user, span_notice("You have converted one of your posters!"))
qdel(src)
+ return ITEM_INTERACT_SUCCESS
/// Screentip for the above
@@ -50,9 +51,8 @@
mood_buff = new(_host = src, range = 7, _ignore_if_not_on_turf = TRUE, department = quirk_poster_department)
return ..()
-/obj/structure/sign/poster/quirk/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
- if (I.tool_behaviour == TOOL_WIRECUTTER)
- QDEL_NULL(mood_buff)
+/obj/structure/sign/poster/quirk/wirecutter_act(mob/living/user, obj/item/tool)
+ QDEL_NULL(mood_buff)
return ..()
/obj/structure/sign/poster/quirk/Destroy()
diff --git a/code/game/objects/items/cigarettes.dm b/code/game/objects/items/cigarettes.dm
index 57b36f1b3e0..a8eefa88ae6 100644
--- a/code/game/objects/items/cigarettes.dm
+++ b/code/game/objects/items/cigarettes.dm
@@ -344,22 +344,24 @@ CIGARETTE PACKETS ARE IN FANCY.DM
user.visible_message(span_suicide("[user] is huffing [src] as quickly as [user.p_they()] can! It looks like [user.p_theyre()] trying to give [user.p_them()]self cancer."))
return (TOXLOSS|OXYLOSS)
-/obj/item/cigarette/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/cigarette/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(lit)
- return ..()
+ return NONE
- var/lighting_text = W.ignition_effect(src, user)
+ var/lighting_text = tool.ignition_effect(src, user)
if(!lighting_text)
- return ..()
+ return NONE
if(!check_oxygen(user)) //cigarettes need oxygen
balloon_alert(user, "no air!")
- return ..()
+ return ITEM_INTERACT_BLOCKING
- if(smoketime > 0)
- light(lighting_text)
- else
+ if(!smoketime)
to_chat(user, span_warning("There is nothing to smoke!"))
+ return ITEM_INTERACT_BLOCKING
+
+ light(lighting_text)
+ return ITEM_INTERACT_SUCCESS
/// Checks that we have enough air to smoke
/obj/item/cigarette/proc/check_oxygen(mob/user)
@@ -971,18 +973,18 @@ CIGARETTE PACKETS ARE IN FANCY.DM
STOP_PROCESSING(SSobj, src)
QDEL_NULL(cig_smoke)
-/obj/item/cigarette/pipe/attackby(obj/item/thing, mob/user, list/modifiers, list/attack_modifiers)
- if(!(istype(thing, /obj/item/food/grown) || istype(thing, /obj/item/food/drug)))
+/obj/item/cigarette/pipe/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!(istype(tool, /obj/item/food/grown) || istype(tool, /obj/item/food/drug)))
return ..()
if(packeditem)
to_chat(user, span_warning("It is already packed!"))
- return
+ return ITEM_INTERACT_BLOCKING
- var/obj/item/to_smoke = thing
+ var/obj/item/to_smoke = tool
if(istype(to_smoke, /obj/item/food/grown) && !HAS_TRAIT(to_smoke, TRAIT_DRIED))
to_chat(user, span_warning("It has to be dried first!"))
- return
+ return ITEM_INTERACT_BLOCKING
to_chat(user, span_notice("You stuff [to_smoke] into [src]."))
smoketime = 13 MINUTES
@@ -991,6 +993,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(to_smoke.reagents)
to_smoke.reagents.trans_to(src, to_smoke.reagents.total_volume, transferred_by = user)
qdel(to_smoke)
+ return ITEM_INTERACT_SUCCESS
/obj/item/cigarette/pipe/attack_self(mob/user)
diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm
index ecc1f76247d..f24b84dc8e0 100644
--- a/code/game/objects/items/circuitboards/computer_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm
@@ -519,19 +519,21 @@
to_chat(user, span_notice("You overload the node announcement chip, forcing every node to be announced on the common channel."))
return TRUE
-/obj/item/circuitboard/computer/rdconsole/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
- if (user.combat_mode || !isidcard(attacking_item))
- return ..()
- if (check_access(attacking_item))
- locked = !locked
- balloon_alert(user, locked ? "locked" : "unlocked")
- user.visible_message(
- message = span_notice("\The [user] unlock[user.p_s()] \the [src] with \the [attacking_item]."),
- self_message = span_notice("You unlock \the [src] with \the [attacking_item]."),
- blind_message = span_hear("You hear a soft beep."),
- )
- else
+/obj/item/circuitboard/computer/rdconsole/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if (user.combat_mode || !isidcard(tool))
+ return NONE
+ if (!check_access(tool))
balloon_alert(user, "no access!")
+ return ITEM_INTERACT_BLOCKING
+ locked = !locked
+ balloon_alert(user, locked ? "locked" : "unlocked")
+ user.visible_message(
+ span_notice("\The [user] unlock[user.p_s()] \the [src] with \the [tool]."),
+ span_notice("You unlock \the [src] with \the [tool]."),
+ span_hear("You hear a soft beep."),
+ )
+ return ITEM_INTERACT_SUCCESS
+
/obj/item/circuitboard/computer/rdservercontrol
name = "R&D Server Control"
diff --git a/code/game/objects/items/courtroom.dm b/code/game/objects/items/courtroom.dm
index f053d84b540..99609766ca0 100644
--- a/code/game/objects/items/courtroom.dm
+++ b/code/game/objects/items/courtroom.dm
@@ -36,10 +36,10 @@
resistance_flags = FLAMMABLE
custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT)
-/obj/item/gavelblock/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(I, /obj/item/gavelhammer))
- playsound(loc, 'sound/items/gavel.ogg', 100, TRUE)
- user.visible_message(span_warning("[user] strikes [src] with [I]."))
- user.changeNext_move(CLICK_CD_MELEE)
- else
- return ..()
+/obj/item/gavelblock/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/gavelhammer))
+ return NONE
+ playsound(loc, 'sound/items/gavel.ogg', 100, TRUE)
+ user.visible_message(span_warning("[user] strikes [src] with [tool]."))
+ user.changeNext_move(CLICK_CD_MELEE)
+ return ITEM_INTERACT_SUCCESS
diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm
index fdb179ba55a..e3cf37392c8 100644
--- a/code/game/objects/items/crab17.dm
+++ b/code/game/objects/items/crab17.dm
@@ -71,32 +71,32 @@
return FALSE
return TRUE
-/obj/structure/checkoutmachine/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
+/obj/structure/checkoutmachine/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(!canwalk)
balloon_alert(user, "not ready to accept transactions!")
- return
+ return ITEM_INTERACT_BLOCKING
if(check_if_finished())
qdel(src)
- return
+ return ITEM_INTERACT_BLOCKING
- var/obj/item/card/id/card = attacking_item.GetID()
+ var/obj/item/card/id/card = tool.GetID()
if(!card)
- balloon_alert(user, "your [attacking_item.name] gets repelled by the id card reader")
+ balloon_alert(user, "the reader repels your [tool.name]")
var/throwtarget = get_step(user, get_dir(src, user))
user.safe_throw_at(throwtarget, 1, 1, force = MOVE_FORCE_EXTREMELY_STRONG)
playsound(get_turf(src),'sound/effects/magic/repulse.ogg', 100, TRUE)
- return
+ return ITEM_INTERACT_BLOCKING
if(!card.registered_account)
balloon_alert(user, "card has no registered account!")
- return
+ return ITEM_INTERACT_BLOCKING
if(!LAZYFIND(card.registered_account.being_dumped, src))
balloon_alert(user, "funds are already safe!")
- return
+ return ITEM_INTERACT_BLOCKING
to_chat(user, span_warning("You quickly cash out your funds to a more secure banking location. Funds are safu.")) // This is a reference and not a typo
accounts_to_rob -= card.registered_account
@@ -104,7 +104,8 @@
if(check_if_finished())
qdel(src)
- return
+
+ return ITEM_INTERACT_SUCCESS
/obj/structure/checkoutmachine/Initialize(mapload, mob/living/user)
. = ..()
diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm
index 71509d389ce..60a4c069081 100644
--- a/code/game/objects/items/devices/laserpointer.dm
+++ b/code/game/objects/items/devices/laserpointer.dm
@@ -91,69 +91,71 @@
crystal_lens = null
return ITEM_INTERACT_SUCCESS
-/obj/item/laser_pointer/attackby(obj/item/attack_item, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(attack_item, /obj/item/stock_parts/micro_laser))
+/obj/item/laser_pointer/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(istype(tool, /obj/item/stock_parts/micro_laser))
if(diode)
balloon_alert(user, "already has a diode!")
- return
- var/obj/item/stock_parts/attack_diode = attack_item
+ return ITEM_INTERACT_BLOCKING
+ var/obj/item/stock_parts/attack_diode = tool
if(crystal_lens && attack_diode.rating < 3) //only tier 3 and up are small enough to fit
- to_chat(user, span_warning("You try to jam \the [attack_item.name] in place, but \the [crystal_lens.name] is in the way!"))
+ to_chat(user, span_warning("You try to jam \the [tool.name] in place, but \the [crystal_lens.name] is in the way!"))
playsound(src, 'sound/machines/airlock/airlock_alien_prying.ogg', 20)
- if(do_after(user, 2 SECONDS, src))
- var/atom/atom_to_teleport = pick(user, attack_item)
- if(atom_to_teleport == user)
- to_chat(user, span_warning("You jam \the [attack_item.name] in too hard and break \the [crystal_lens.name] inside, teleporting you away!"))
- user.drop_all_held_items()
- else if(atom_to_teleport == attack_item)
- attack_item.forceMove(drop_location())
- to_chat(user, span_warning("You jam \the [attack_item.name] in too hard and break \the [crystal_lens.name] inside, teleporting \the [attack_item.name] away!"))
- do_teleport(atom_to_teleport, get_turf(src), crystal_lens.blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
- qdel(crystal_lens)
- return
- if(!user.transferItemToLoc(attack_item, src))
- return
+ if(!do_after(user, 2 SECONDS, src))
+ return ITEM_INTERACT_BLOCKING
+ var/atom/atom_to_teleport = pick(user, tool)
+ if(atom_to_teleport == user)
+ to_chat(user, span_warning("You jam \the [tool.name] in too hard and break \the [crystal_lens.name] inside, teleporting you away!"))
+ user.drop_all_held_items()
+ else if(atom_to_teleport == tool)
+ tool.forceMove(drop_location())
+ to_chat(user, span_warning("You jam \the [tool.name] in too hard and break \the [crystal_lens.name] inside, teleporting \the [tool.name] away!"))
+ do_teleport(atom_to_teleport, get_turf(src), crystal_lens.blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
+ qdel(crystal_lens)
+ return ITEM_INTERACT_SUCCESS
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
playsound(src, 'sound/items/tools/screwdriver.ogg', 30)
- diode = attack_item
+ diode = tool
balloon_alert(user, "installed \the [diode.name]")
//we have a diode now, try starting a charge sequence in case the pointer was charging when we took out the diode
recharging = TRUE
START_PROCESSING(SSobj, src)
- return TRUE
+ return ITEM_INTERACT_SUCCESS
- if(istype(attack_item, /obj/item/stack/ore/bluespace_crystal))
+ if(istype(tool, /obj/item/stack/ore/bluespace_crystal))
if(crystal_lens)
balloon_alert(user, "already has a lens!")
- return
+ return ITEM_INTERACT_BLOCKING
//the crystal stack we're trying to install a crystal from
- var/obj/item/stack/ore/bluespace_crystal/crystal_stack = attack_item
+ var/obj/item/stack/ore/bluespace_crystal/crystal_stack = tool
if(diode && diode.rating < 3) //only lasers of tier 3 and up can house a lens
to_chat(user, span_warning("You try to jam \the [crystal_stack.name] in front of the diode, but it's a bad fit!"))
playsound(src, 'sound/machines/airlock/airlock_alien_prying.ogg', 20)
- if(do_after(user, 2 SECONDS, src))
- var/atom/atom_to_teleport = pick(user, src)
- if(atom_to_teleport == user)
- to_chat(user, span_warning("You press on \the [crystal_stack.name] too hard and are teleported away!"))
- user.drop_all_held_items()
- else if(atom_to_teleport == src)
- forceMove(drop_location())
- to_chat(user, span_warning("You press on \the [crystal_stack.name] too hard and \the [src] is teleported away!"))
- do_teleport(atom_to_teleport, get_turf(src), crystal_stack.blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
- crystal_stack.use_tool(src, user, amount = 1) //use only one if we were installing from a stack of crystals
- return
+ if(!do_after(user, 2 SECONDS, src))
+ return ITEM_INTERACT_BLOCKING
+ var/atom/atom_to_teleport = pick(user, src)
+ if(atom_to_teleport == user)
+ to_chat(user, span_warning("You press on \the [crystal_stack.name] too hard and are teleported away!"))
+ user.drop_all_held_items()
+ else if(atom_to_teleport == src)
+ forceMove(drop_location())
+ to_chat(user, span_warning("You press on \the [crystal_stack.name] too hard and \the [src] is teleported away!"))
+ do_teleport(atom_to_teleport, get_turf(src), crystal_stack.blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
+ crystal_stack.use_tool(src, user, amount = 1) //use only one if we were installing from a stack of crystals
+ return ITEM_INTERACT_SUCCESS
//the single crystal that we actually install
var/obj/item/stack/ore/bluespace_crystal/single_crystal = crystal_stack.split_stack(1)
if(isnull(single_crystal))
- return
+ return ITEM_INTERACT_BLOCKING
single_crystal.forceMove(src)
crystal_lens = single_crystal
playsound(src, 'sound/items/tools/screwdriver2.ogg', 30)
balloon_alert(user, "installed \the [crystal_lens.name]")
to_chat(user, span_notice("You install a [crystal_lens.name] in [src]. \
It can now be used to shine through obstacles at the cost of double the energy drain."))
- return TRUE
+ return ITEM_INTERACT_SUCCESS
- return ..()
+ return NONE
/obj/item/laser_pointer/examine(mob/user)
. = ..()
diff --git a/code/game/objects/items/devices/pressureplates.dm b/code/game/objects/items/devices/pressureplates.dm
index d1bff2e7432..69a7cc018a1 100644
--- a/code/game/objects/items/devices/pressureplates.dm
+++ b/code/game/objects/items/devices/pressureplates.dm
@@ -64,17 +64,19 @@
if(istype(assembly))
assembly.activate()
-/obj/item/pressure_plate/attackby(obj/item/item, mob/living/L)
- if(isassembly(item) && !istype(assembly) && removable_assembly)
- var/obj/item/assembly/new_assembly = item
- if(!(new_assembly.assembly_behavior & ASSEMBLY_FUNCTIONAL_OUTPUT))
- to_chat(L, span_warning("\The [item] doesn't seem like it would do much of anything inside of [src]..."))
- return
- if(L.transferItemToLoc(item, src))
- assembly = item
- SEND_SIGNAL(item, COMSIG_ASSEMBLY_ADDED_TO_PRESSURE_PLATE, src, L)
- to_chat(L, span_notice("You attach [item] to [src]!"))
- return ..()
+/obj/item/pressure_plate/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!isassembly(tool) || assembly || !removable_assembly)
+ return NONE
+ var/obj/item/assembly/new_assembly = tool
+ if(!(new_assembly.assembly_behavior & ASSEMBLY_FUNCTIONAL_OUTPUT))
+ to_chat(user, span_warning("\The [tool] doesn't seem like it would do much of anything inside of [src]..."))
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
+ assembly = tool
+ SEND_SIGNAL(tool, COMSIG_ASSEMBLY_ADDED_TO_PRESSURE_PLATE, src, user)
+ to_chat(user, span_notice("You attach [tool] to [src]!"))
+ return ITEM_INTERACT_SUCCESS
/obj/item/pressure_plate/attack_self(mob/living/L)
if(removable_assembly && istype(assembly))
diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm
index 7b3d48a69dd..d1645e98fa6 100644
--- a/code/game/objects/items/devices/radio/electropack.dm
+++ b/code/game/objects/items/devices/radio/electropack.dm
@@ -40,25 +40,28 @@
return
return ..()
-/obj/item/electropack/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(W, /obj/item/clothing/head/helmet))
- var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user)
- A.icon = 'icons/obj/devices/assemblies.dmi'
+/obj/item/electropack/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/clothing/head/helmet))
+ return NONE
+ if(!user.temporarilyRemoveItemFromInventory(tool))
+ to_chat(user, span_warning("[tool] is stuck to your hand, you cannot attach it to [src]!"))
+ return ITEM_INTERACT_BLOCKING
+ var/obj/item/assembly/shock_kit/torture_device = new /obj/item/assembly/shock_kit(user)
+ torture_device.icon = 'icons/obj/devices/assemblies.dmi'
- if(!user.transferItemToLoc(W, A))
- to_chat(user, span_warning("[W] is stuck to your hand, you cannot attach it to [src]!"))
- return
- W.master = A
- A.helmet_part = W
+ tool.forceMove(torture_device) // Forcemove() because we've already seen we can move it with the check above and the check above forces us to use forceMove() next
- user.transferItemToLoc(src, A, TRUE)
- master = A
- A.electropack_part = src
+ tool.master = torture_device
+ torture_device.helmet_part = tool
- user.put_in_hands(A)
- A.add_fingerprint(user)
- else
- return ..()
+ user.transferItemToLoc(src, torture_device, TRUE)
+ master = torture_device
+ torture_device.electropack_part = src
+
+ user.put_in_hands(torture_device)
+ torture_device.add_fingerprint(user)
+
+ return ITEM_INTERACT_SUCCESS
/obj/item/electropack/receive_signal(datum/signal/signal)
if(!signal || signal.data["code"] != code)
diff --git a/code/game/objects/items/devices/swapper.dm b/code/game/objects/items/devices/swapper.dm
index 01fda4b6456..642f0c80589 100644
--- a/code/game/objects/items/devices/swapper.dm
+++ b/code/game/objects/items/devices/swapper.dm
@@ -27,22 +27,22 @@
icon_state = "swapper[linked_swapper ? "-linked" : null]"
return ..()
-/obj/item/swapper/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(I, /obj/item/swapper))
- var/obj/item/swapper/other_swapper = I
- if(other_swapper.linked_swapper)
- to_chat(user, span_warning("[other_swapper] is already linked. Break the current link to establish a new one."))
- return
- if(linked_swapper)
- to_chat(user, span_warning("[src] is already linked. Break the current link to establish a new one."))
- return
- to_chat(user, span_notice("You establish a quantum link between the two devices."))
- linked_swapper = other_swapper
- other_swapper.linked_swapper = src
- update_appearance()
- linked_swapper.update_appearance()
- else
- return ..()
+/obj/item/swapper/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/swapper))
+ return NONE
+ var/obj/item/swapper/other_swapper = tool
+ if(other_swapper.linked_swapper)
+ to_chat(user, span_warning("[other_swapper] is already linked. Break the current link to establish a new one."))
+ return ITEM_INTERACT_BLOCKING
+ if(linked_swapper)
+ to_chat(user, span_warning("[src] is already linked. Break the current link to establish a new one."))
+ return ITEM_INTERACT_BLOCKING
+ to_chat(user, span_notice("You establish a quantum link between the two devices."))
+ linked_swapper = other_swapper
+ other_swapper.linked_swapper = src
+ update_appearance()
+ linked_swapper.update_appearance()
+ return ITEM_INTERACT_SUCCESS
/obj/item/swapper/attack_self(mob/living/user)
if(world.time < next_use)
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index 7e34b98a874..7b7286b9711 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -84,15 +84,16 @@
else
soundloop.start()
-/obj/item/taperecorder/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
- if(!mytape && istype(I, /obj/item/tape))
- if(!user.transferItemToLoc(I,src))
- return
- mytape = I
- balloon_alert(user, "inserted [mytape]")
- playsound(src, 'sound/items/taperecorder/taperecorder_close.ogg', 50, FALSE)
- update_appearance()
-
+/obj/item/taperecorder/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(mytape || !istype(tool, /obj/item/tape))
+ return NONE
+ if(!user.transferItemToLoc(tool,src))
+ return ITEM_INTERACT_BLOCKING
+ mytape = tool
+ balloon_alert(user, "inserted [mytape]")
+ playsound(src, 'sound/items/taperecorder/taperecorder_close.ogg', 50, FALSE)
+ update_appearance()
+ return ITEM_INTERACT_SUCCESS
/obj/item/taperecorder/proc/eject(mob/user)
if(!mytape)
diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm
index 0ba47962beb..4737c49dc51 100644
--- a/code/game/objects/items/devices/traitordevices.dm
+++ b/code/game/objects/items/devices/traitordevices.dm
@@ -442,35 +442,39 @@ effective or pretty fucking useless.
return TRUE
-/obj/machinery/porta_turret/syndicate/toolbox/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
- if(!istype(attacking_item, /obj/item/wrench/combat))
+/obj/machinery/porta_turret/syndicate/toolbox/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/wrench/combat))
return ..()
- if(!attacking_item.toolspeed)
- return
+ if(!tool.toolspeed) // This is a check for the laser wrench being off, I think
+ return ITEM_INTERACT_BLOCKING
if(user.combat_mode)
balloon_alert(user, "deconstructing...")
- if(!attacking_item.use_tool(src, user, 5 SECONDS, volume = 20))
- return
+ if(!tool.use_tool(src, user, 5 SECONDS, volume = 20))
+ return ITEM_INTERACT_BLOCKING
deconstruct(TRUE)
- attacking_item.play_tool_sound(src, 50)
+ tool.play_tool_sound(src, 50)
balloon_alert(user, "deconstructed!")
+ return ITEM_INTERACT_SUCCESS
- else
- if(atom_integrity == max_integrity)
- balloon_alert(user, "already repaired!")
- return
- balloon_alert(user, "repairing...")
- while(atom_integrity != max_integrity)
- if(!attacking_item.use_tool(src, user, 2 SECONDS, volume = 20))
- return
+ if(atom_integrity == max_integrity)
+ balloon_alert(user, "already repaired!")
+ return ITEM_INTERACT_BLOCKING
- repair_damage(10)
+ balloon_alert(user, "repairing...")
+ . = ITEM_INTERACT_BLOCKING // I'm doing this such that at least one successful repair considers the interaction a success
+ while(atom_integrity != max_integrity)
+ if(!tool.use_tool(src, user, 2 SECONDS, volume = 20))
+ return .
- balloon_alert(user, "repaired!")
+ repair_damage(10)
+ . = ITEM_INTERACT_SUCCESS
+
+ balloon_alert(user, "repaired!")
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/porta_turret/syndicate/toolbox/on_deconstruction(disassembled)
if(disassembled)
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index b90a02db9ea..7dcf6fa1061 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -118,33 +118,42 @@
return ITEM_INTERACT_FAILURE
return NONE
-/obj/item/transfer_valve/attackby(obj/item/item, mob/user, params)
- if(istype(item, /obj/item/tank))
- try_attach_tank(item, user)
-//TODO: Have this take an assemblyholder
- else if(isassembly(item))
- try_attach_assembly(item, user)
- else if(istype(item, /obj/item/stack/cable_coil) && !wired)
- var/obj/item/stack/cable_coil/coil = item
+/obj/item/transfer_valve/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(istype(tool, /obj/item/tank))
+ try_attach_tank(tool, user)
+ return ITEM_INTERACT_SUCCESS
+
+ //TODO: Have this take an assemblyholder <-- commit five years ago
+ if(isassembly(tool))
+ try_attach_assembly(tool, user)
+ return ITEM_INTERACT_SUCCESS
+
+ if(istype(tool, /obj/item/stack/cable_coil) && !wired)
+ var/obj/item/stack/cable_coil/coil = tool
if (coil.get_amount() < 15)
to_chat(user, span_warning("You need fifteen lengths of coil for this!"))
- return
+ return ITEM_INTERACT_BLOCKING
coil.use(15)
to_chat(user, span_notice("You add some cables, not being really sure why. Looks like backpack straps."))
wired = TRUE
slot_flags |= ITEM_SLOT_BACK
update_appearance()
+ return ITEM_INTERACT_SUCCESS
- else if(item.tool_behaviour == TOOL_WIRECUTTER && wired)
- item.play_tool_sound(src)
- to_chat(user, span_notice("You remove the cables."))
- wired = FALSE
- slot_flags &= ~ITEM_SLOT_BACK
- Move(drop_location())
- new /obj/item/stack/cable_coil(drop_location(), 15)
- update_appearance()
+ return NONE
+
+/obj/item/transfer_valve/wirecutter_act(mob/living/user, obj/item/tool)
+ if(!wired)
+ return ITEM_INTERACT_SKIP_TO_ATTACK
+ tool.play_tool_sound(src)
+ to_chat(user, span_notice("You remove the cables."))
+ wired = FALSE
+ slot_flags &= ~ITEM_SLOT_BACK
+ forceMove(drop_location())
+ new /obj/item/stack/cable_coil(drop_location(), 15)
+ update_appearance()
+ return ITEM_INTERACT_SUCCESS
- return
/obj/item/transfer_valve/proc/try_attach_tank(obj/item/tank/new_tank, mob/user)
if(!tank_one)
diff --git a/code/game/objects/items/grenades/festive.dm b/code/game/objects/items/grenades/festive.dm
index faa8d8da5bf..cdc651b3c38 100644
--- a/code/game/objects/items/grenades/festive.dm
+++ b/code/game/objects/items/grenades/festive.dm
@@ -14,12 +14,12 @@
/obj/item/sparkler/fire_act(exposed_temperature, exposed_volume)
light()
-/obj/item/sparkler/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
- var/ignition_msg = item.ignition_effect(src, user)
- if(ignition_msg)
- light(user, ignition_msg)
- else
- return ..()
+/obj/item/sparkler/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ var/ignition_msg = tool.ignition_effect(src, user)
+ if(!ignition_msg)
+ return NONE
+ light(user, ignition_msg)
+ return ITEM_INTERACT_SUCCESS
/obj/item/sparkler/proc/light(mob/user, message)
if(lit)
@@ -75,13 +75,15 @@
/obj/item/grenade/firecracker/attack_self(mob/user) // You need to light it manually.
return
-/obj/item/grenade/firecracker/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
- var/ignition_msg = item.ignition_effect(src, user)
- if(ignition_msg && !active)
- visible_message(ignition_msg)
- arm_grenade(user)
- else
- return ..()
+/obj/item/grenade/firecracker/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(active)
+ return NONE
+ var/ignition_msg = tool.ignition_effect(src, user)
+ if(!ignition_msg)
+ return NONE
+ visible_message(ignition_msg)
+ arm_grenade(user)
+ return ITEM_INTERACT_SUCCESS
/obj/item/grenade/firecracker/fire_act(exposed_temperature, exposed_volume)
detonate()
diff --git a/code/game/objects/items/grenades/ghettobomb.dm b/code/game/objects/items/grenades/ghettobomb.dm
index ac1c444cbd5..779ff29f169 100644
--- a/code/game/objects/items/grenades/ghettobomb.dm
+++ b/code/game/objects/items/grenades/ghettobomb.dm
@@ -218,33 +218,33 @@
else
. += span_notice("The wires are just dangling from it, you need some sort of activating assembly.")
-/obj/item/sliced_pipe/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/sliced_pipe/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(!wires_are_in)
// here we can stuff in additional objects for a cooler effect
- if(is_type_in_typecache(item, allowed) && contents.len < MAX_STUFFINGS)
+ if(is_type_in_typecache(tool, allowed) && contents.len < MAX_STUFFINGS)
balloon_alert(user, "stuffed in")
- var/atom/movable/to_put = item
- if(isstack(item))
- var/obj/item/stack/as_stack = item
+ var/atom/movable/to_put = tool
+ if(isstack(tool))
+ var/obj/item/stack/as_stack = tool
var/obj/item/stack/new_stack = as_stack.split_stack(1)
new_stack.merge_type = null //prevent them from merging inside for contents.len
to_put = new_stack
to_put.forceMove(src)
- return
+ return ITEM_INTERACT_SUCCESS
//if the item has reagents lets allow it to transfer
- if(item.reagents)
- return ..()
+ if(tool.reagents)
+ return NONE
if(reagents.total_volume < 5)
balloon_alert(user, "add more fuel!")
- return
+ return ITEM_INTERACT_BLOCKING
- var/obj/item/stack/cable_coil/coil = item
+ var/obj/item/stack/cable_coil/coil = tool
if(!istype(coil))
- return
+ return ITEM_INTERACT_BLOCKING
if (coil.get_amount() < 15)
balloon_alert(user, "need 15 length!")
- return
+ return ITEM_INTERACT_BLOCKING
coil.use(15)
var/cur_power = 0
@@ -260,27 +260,30 @@
icon_state = "[icon_state]-cable"
reagents.flags = SEALED_CONTAINER
wires_are_in = TRUE
- else // wires are in, lets finish this up
- var/obj/item/assembly/assembly = item
- if(!istype(assembly) || !(assembly.type in allowed_activators))
- return
- if(assembly.secured)
- balloon_alert(user, "unsecure assembly first!")
- return
- if(!user.transferItemToLoc(assembly, src))
- return
- user.balloon_alert(user, "attached")
+ return ITEM_INTERACT_SUCCESS
- var/obj/item/grenade/iedcasing/pipebomb = new(drop_location())
- for(var/atom/movable/item_inside as anything in contents)
- item_inside.forceMove(pipebomb)
+ // wires are in, lets finish this up
+ var/obj/item/assembly/assembly = tool
+ if(!istype(assembly) || !(assembly.type in allowed_activators))
+ return ITEM_INTERACT_BLOCKING
+ if(assembly.secured)
+ balloon_alert(user, "unsecure assembly first!")
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(assembly, src))
+ return ITEM_INTERACT_BLOCKING
+ user.balloon_alert(user, "attached")
- pipebomb.power = power
- pipebomb.attach_activator(assembly)
- pipebomb.setup_effects_from_contents()
- var/was_in_hands = (loc == user)
- qdel(src)
- if(was_in_hands)
- user.put_in_hands(pipebomb)
+ var/obj/item/grenade/iedcasing/pipebomb = new(drop_location())
+ for(var/atom/movable/item_inside as anything in contents)
+ item_inside.forceMove(pipebomb)
+
+ pipebomb.power = power
+ pipebomb.attach_activator(assembly)
+ pipebomb.setup_effects_from_contents()
+ var/was_in_hands = (loc == user)
+ qdel(src)
+ if(was_in_hands)
+ user.put_in_hands(pipebomb)
+ return ITEM_INTERACT_SUCCESS
#undef MAX_STUFFINGS
diff --git a/code/game/objects/items/implants/implantpad.dm b/code/game/objects/items/implants/implantpad.dm
index 094e8d51676..7faa508b760 100644
--- a/code/game/objects/items/implants/implantpad.dm
+++ b/code/game/objects/items/implants/implantpad.dm
@@ -40,15 +40,16 @@
inserted_case = null
update_appearance(UPDATE_ICON)
-/obj/item/implantpad/attackby(obj/item/implantcase/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
- if(inserted_case || !istype(attacking_item))
- return ..()
- if(!user.transferItemToLoc(attacking_item, src))
- return
+/obj/item/implantpad/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(inserted_case || !istype(tool, /obj/item/implantcase))
+ return NONE
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
user.balloon_alert(user, "case inserted")
- inserted_case = attacking_item
+ inserted_case = tool
update_static_data_for_all_viewers()
update_appearance(UPDATE_ICON)
+ return ITEM_INTERACT_SUCCESS
/obj/item/implantpad/click_alt(mob/user)
remove_implant(user)
diff --git a/code/game/objects/items/kirby_plants/kirbyplants.dm b/code/game/objects/items/kirby_plants/kirbyplants.dm
index 1f665499601..b9920ea16b6 100644
--- a/code/game/objects/items/kirby_plants/kirbyplants.dm
+++ b/code/game/objects/items/kirby_plants/kirbyplants.dm
@@ -50,19 +50,23 @@
. = ..()
icon_state = dead ? "plant-25" : base_icon_state
-/obj/item/kirbyplants/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers)
- . = ..()
- if(!dead && trimmable && HAS_TRAIT(user,TRAIT_BONSAI) && isturf(loc) && I.get_sharpness())
+/obj/item/kirbyplants/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!dead && trimmable && HAS_TRAIT(user, TRAIT_BONSAI) && isturf(loc) && tool.get_sharpness())
to_chat(user,span_notice("You start trimming [src]."))
- if(do_after(user,3 SECONDS,target=src))
- to_chat(user,span_notice("You finish trimming [src]."))
- change_visual()
- if(dead && istype(I, /obj/item/seeds))
+ if(!do_after(user, 3 SECONDS, target = src))
+ return ITEM_INTERACT_BLOCKING
+ to_chat(user,span_notice("You finish trimming [src]."))
+ change_visual()
+
+ if(dead && istype(tool, /obj/item/seeds))
to_chat(user,span_notice("You start planting a new seed into the pot."))
- if(do_after(user,3 SECONDS,target=src))
- qdel(I)
- dead = FALSE
- update_appearance()
+ if(!do_after(user, 3 SECONDS, target = src))
+ return ITEM_INTERACT_BLOCKING
+ qdel(tool)
+ dead = FALSE
+ update_appearance()
+
+ return NONE
/// Cycle basic plant visuals
/obj/item/kirbyplants/proc/change_visual()
diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm
index f9eb7b87c31..7d314b0903e 100644
--- a/code/game/objects/items/latexballoon.dm
+++ b/code/game/objects/items/latexballoon.dm
@@ -101,16 +101,17 @@
burst()
return ..()
-/obj/item/latexballoon/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(item, /obj/item/tank))
- var/obj/item/tank/air_tank = item
+/obj/item/latexballoon/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(istype(tool, /obj/item/tank))
+ var/obj/item/tank/air_tank = tool
blow(air_tank, user)
- return
- if(item.get_sharpness() || item.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
- burst()
- return
+ return ITEM_INTERACT_SUCCESS
- return ..()
+ if(tool.get_sharpness() || tool.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
+ burst()
+ return ITEM_INTERACT_SUCCESS
+
+ return NONE
#undef INFLATED
#undef POPPED
diff --git a/code/game/objects/items/mail.dm b/code/game/objects/items/mail.dm
index bebc7b4ceab..f16ae3fe5b2 100644
--- a/code/game/objects/items/mail.dm
+++ b/code/game/objects/items/mail.dm
@@ -98,16 +98,19 @@
postmark_image.appearance_flags |= RESET_COLOR|KEEP_APART
. += postmark_image
-/obj/item/mail/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/mail/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
// Destination tagging
- if(istype(W, /obj/item/dest_tagger))
- var/obj/item/dest_tagger/destination_tag = W
+ if(!istype(tool, /obj/item/dest_tagger))
+ return NONE
+ var/obj/item/dest_tagger/destination_tag = tool
- if(sort_tag != destination_tag.currTag)
- var/tag = uppertext(GLOB.TAGGERLOCATIONS[destination_tag.currTag])
- to_chat(user, span_notice("*[tag]*"))
- sort_tag = destination_tag.currTag
- playsound(loc, 'sound/machines/beep/twobeep_high.ogg', vol = 100, vary = TRUE)
+ if(sort_tag == destination_tag.currTag)
+ return ITEM_INTERACT_BLOCKING
+ var/tag = uppertext(GLOB.TAGGERLOCATIONS[destination_tag.currTag])
+ to_chat(user, span_notice("*[tag]*"))
+ sort_tag = destination_tag.currTag
+ playsound(loc, 'sound/machines/beep/twobeep_high.ogg', vol = 100, vary = TRUE)
+ return ITEM_INTERACT_SUCCESS
/obj/item/mail/multitool_act(mob/living/user, obj/item/tool)
if(user.get_inactive_held_item() == src)
diff --git a/code/game/objects/items/piggy_bank.dm b/code/game/objects/items/piggy_bank.dm
index 117220a0aac..1f53e0c80cb 100644
--- a/code/game/objects/items/piggy_bank.dm
+++ b/code/game/objects/items/piggy_bank.dm
@@ -124,23 +124,28 @@
if(95 to INFINITY)
balloon_alert(user, "brimming with cash")
-/obj/item/piggy_bank/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
- var/creds_value = item.get_item_credit_value()
+/obj/item/piggy_bank/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ var/creds_value = tool.get_item_credit_value()
if(isnull(creds_value))
- return ..()
+ return NONE
var/dosh_amount = calculate_dosh_amount()
if(dosh_amount >= maximum_value)
balloon_alert(user, "it's full!")
- else if(dosh_amount + creds_value > maximum_value)
+ return ITEM_INTERACT_BLOCKING
+
+ if(dosh_amount + creds_value > maximum_value)
balloon_alert(user, "too much cash!")
- else if(!user.transferItemToLoc(item, src))
+ return ITEM_INTERACT_BLOCKING
+
+ if(!user.transferItemToLoc(tool, src))
balloon_alert(user, "stuck in your hands!")
- else
- balloon_alert(user, "inserted [creds_value] creds")
- sanitize_piggy_bank_contents_len()
- return TRUE
+ return ITEM_INTERACT_BLOCKING
+
+ balloon_alert(user, "inserted [creds_value] creds")
+ sanitize_piggy_bank_contents_len()
+ return ITEM_INTERACT_SUCCESS
///Returns the total amount of credits that its contents amount to.
/obj/item/piggy_bank/proc/calculate_dosh_amount()
diff --git a/code/game/objects/items/pillow.dm b/code/game/objects/items/pillow.dm
index 2ccf7157b83..3eb167e25d6 100644
--- a/code/game/objects/items/pillow.dm
+++ b/code/game/objects/items/pillow.dm
@@ -73,29 +73,31 @@
user.visible_message("[user] starts to smother [victim]", span_notice("You begin smothering [victim]"), vision_distance = COMBAT_MESSAGE_RANGE)
INVOKE_ASYNC(src, PROC_REF(smothering), user, victim)
-/obj/item/pillow/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
- if(!bricked && istype(attacking_item, /obj/item/stack/sheet/mineral/sandstone))
- var/obj/item/stack/sheet/mineral/sandstone/brick = attacking_item
+/obj/item/pillow/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!bricked && istype(tool, /obj/item/stack/sheet/mineral/sandstone))
+ var/obj/item/stack/sheet/mineral/sandstone/brick = tool
balloon_alert(user, "inserting brick...")
if(!do_after(user, 2 SECONDS, src))
- return
+ return ITEM_INTERACT_BLOCKING
if(!brick.use(1))
balloon_alert(user, "not enough bricks!")
- return
+ return ITEM_INTERACT_BLOCKING
balloon_alert(user, "bricked!")
become_bricked()
- return
- if(istype(attacking_item, /obj/item/clothing/neck/pillow_tag))
- if(!pillow_trophy)
- user.transferItemToLoc(attacking_item, src)
- pillow_trophy = attacking_item
- balloon_alert(user, "honor reclaimed!")
- update_appearance()
- return
- else
+ return ITEM_INTERACT_SUCCESS
+
+ if(istype(tool, /obj/item/clothing/neck/pillow_tag))
+ if(pillow_trophy)
balloon_alert(user, "tag is intact.")
- return
- return ..()
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
+ pillow_trophy = tool
+ balloon_alert(user, "honor reclaimed!")
+ update_appearance()
+ return ITEM_INTERACT_SUCCESS
+
+ return NONE
/obj/item/pillow/examine(mob/user)
. = ..()
diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm
index 48e5f14d0c6..8abf3d0057e 100644
--- a/code/game/objects/items/plushes.dm
+++ b/code/game/objects/items/plushes.dm
@@ -131,50 +131,54 @@
else
to_chat(user, span_notice("You try to pet [src], but it has no stuffing. Aww..."))
-/obj/item/toy/plush/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers)
- if(I.get_sharpness())
- if(!grenade)
- if(!stuffed)
- to_chat(user, span_warning("You already murdered it!"))
- return
- if(!divine)
- user.visible_message(span_notice("[user] tears out the stuffing from [src]!"), span_notice("You rip a bunch of the stuffing from [src]. Murderer."))
- I.play_tool_sound(src)
- stuffed = FALSE
- else
- to_chat(user, span_notice("What a fool you are. [src] is a god, how can you kill a god? What a grand and intoxicating innocence."))
- user.adjust_drunk_effect(20, up_to = 50)
-
- var/turf/current_location = get_turf(user)
- var/area/current_area = current_location.loc //copied from hand tele code
- if(current_location && current_area && (current_area.area_flags & NOTELEPORT))
- to_chat(user, span_notice("There is no escape. No recall or intervention can work in this place."))
- else
- to_chat(user, span_notice("There is no escape. Although recall or intervention can work in this place, attempting to flee from [src]'s immense power would be futile."))
- user.visible_message(span_notice("[user] lays down their weapons and begs for [src]'s mercy!"), span_notice("You lay down your weapons and beg for [src]'s mercy."))
- user.drop_all_held_items()
- else
+/obj/item/toy/plush/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(tool.get_sharpness())
+ if(grenade)
to_chat(user, span_notice("You remove the grenade from [src]."))
user.put_in_hands(grenade)
- return
- if(isgrenade(I))
+ return ITEM_INTERACT_SUCCESS
+ if(!stuffed)
+ to_chat(user, span_warning("You already murdered it!"))
+ return ITEM_INTERACT_BLOCKING
+ if(!divine)
+ user.visible_message(span_notice("[user] tears out the stuffing from [src]!"), span_notice("You rip a bunch of the stuffing from [src]. Murderer."))
+ tool.play_tool_sound(src)
+ stuffed = FALSE
+ return ITEM_INTERACT_SUCCESS
+
+ to_chat(user, span_notice("What a fool you are. [src] is a god, how can you kill a god? What a grand and intoxicating innocence."))
+ user.adjust_drunk_effect(20, up_to = 50)
+
+ var/turf/current_location = get_turf(user)
+ var/area/current_area = current_location.loc //copied from hand tele code
+ if(current_location && current_area && (current_area.area_flags & NOTELEPORT))
+ to_chat(user, span_notice("There is no escape. No recall or intervention can work in this place."))
+ else
+ to_chat(user, span_notice("There is no escape. Although recall or intervention can work in this place, attempting to flee from [src]'s immense power would be futile."))
+ user.visible_message(span_notice("[user] lays down their weapons and begs for [src]'s mercy!"), span_notice("You lay down your weapons and beg for [src]'s mercy."))
+ user.drop_all_held_items()
+ return ITEM_INTERACT_SUCCESS
+
+ if(isgrenade(tool))
if(stuffed)
to_chat(user, span_warning("You need to remove some stuffing first!"))
- return
+ return ITEM_INTERACT_BLOCKING
if(grenade)
to_chat(user, span_warning("[src] already has a grenade!"))
- return
- if(!user.transferItemToLoc(I, src))
- return
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
user.visible_message(span_warning("[user] slides [grenade] into [src]."), \
- span_danger("You slide [I] into [src]."))
- grenade = I
- user.log_message("added a grenade ([I.name]) to [src]", LOG_GAME)
- return
- if(istype(I, /obj/item/toy/plush))
- love(I, user)
- return
- return ..()
+ span_danger("You slide [tool] into [src]."))
+ grenade = tool
+ user.log_message("added a grenade ([tool.name]) to [src]", LOG_GAME)
+ return ITEM_INTERACT_SUCCESS
+
+ if(istype(tool, /obj/item/toy/plush))
+ love(tool, user)
+ return ITEM_INTERACT_SUCCESS
+
+ return NONE
/obj/item/toy/plush/proc/love(obj/item/toy/plush/Kisser, mob/living/user) //~<3
var/chance = 100 //to steal a kiss, surely there's a 100% chance no-one would reject a plush such as I?
diff --git a/code/game/objects/items/rcd/RCL.dm b/code/game/objects/items/rcd/RCL.dm
index 6c48d2f691d..45768399a90 100644
--- a/code/game/objects/items/rcd/RCL.dm
+++ b/code/game/objects/items/rcd/RCL.dm
@@ -72,30 +72,34 @@
loaded = null
update_appearance()
-/obj/item/rcl/attackby(obj/item/W, mob/user)
- if(istype(W, /obj/item/stack/pipe_cleaner_coil))
- var/obj/item/stack/pipe_cleaner_coil/C = W
+/obj/item/rcl/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/stack/pipe_cleaner_coil))
+ return NONE
- if(!loaded)
- if(!user.transferItemToLoc(W, src))
- to_chat(user, span_warning("[src] is stuck to your hand!"))
- return
- else
- loaded = W //W.loc is src at this point.
- loaded.set_pipecleaner_color(colors[current_color_index])
- loaded.max_amount = max_amount //We store a lot.
- return
- if(loaded.amount < max_amount)
- var/transfer_amount = min(max_amount - loaded.amount, C.amount)
- C.use(transfer_amount)
- loaded.amount += transfer_amount
- else
- return
+ if(!loaded)
+ if(!user.transferItemToLoc(tool, src))
+ to_chat(user, span_warning("[src] is stuck to your hand!"))
+ return ITEM_INTERACT_BLOCKING
+
+ loaded = tool //tool.loc is src at this point.
+ loaded.set_pipecleaner_color(colors[current_color_index])
+ loaded.max_amount = max_amount //We store a lot.
update_appearance()
- to_chat(user, span_notice("You add the pipe cleaners to [src]. It now contains [loaded.amount]."))
- else
- ..()
+ return ITEM_INTERACT_SUCCESS
+
+ var/obj/item/stack/pipe_cleaner_coil/loading_coil = tool
+
+ if(loaded.amount >= max_amount)
+ return ITEM_INTERACT_BLOCKING
+
+ var/transfer_amount = min(max_amount - loaded.amount, loading_coil.amount)
+ loading_coil.use(transfer_amount)
+ loaded.amount += transfer_amount
+
+ update_appearance()
+ to_chat(user, span_notice("You add the pipe cleaners to [src]. It now contains [loaded.amount]."))
+ return ITEM_INTERACT_SUCCESS
/obj/item/rcl/examine(mob/user)
. = ..()
diff --git a/code/game/objects/items/rcd/RSF.dm b/code/game/objects/items/rcd/RSF.dm
index 1dff040fcfd..dbde9ab8cdd 100644
--- a/code/game/objects/items/rcd/RSF.dm
+++ b/code/game/objects/items/rcd/RSF.dm
@@ -72,23 +72,25 @@ RSF
/obj/item/rsf/cyborg
matter = 30
-/obj/item/rsf/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(is_type_in_list(W,matter_by_item))//If the thing we got hit by is in our matter list
- var/tempMatter = matter_by_item[W.type] + matter
- if(tempMatter > max_matter)
- to_chat(user, span_warning("\The [src] can't hold any more [discriptor]!"))
- return
- if(isstack(W))
- var/obj/item/stack/stack = W
- stack.use(1)
- else
- qdel(W)
- matter = tempMatter //We add its value
- playsound(src.loc, 'sound/machines/click.ogg', 10, TRUE)
- to_chat(user, span_notice("\The [src] now holds [matter]/[max_matter] [discriptor]."))
- icon_state = base_icon_state//and set the icon state to the base state
+/obj/item/rsf/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!is_type_in_list(tool, matter_by_item))//If the thing we got hit by is in our matter list
+ return NONE
+
+ var/tempMatter = matter_by_item[tool.type] + matter
+ if(tempMatter > max_matter)
+ to_chat(user, span_warning("\The [src] can't hold any more [discriptor]!"))
+ return ITEM_INTERACT_BLOCKING
+
+ if(isstack(tool))
+ var/obj/item/stack/stack = tool
+ stack.use(1)
else
- return ..()
+ qdel(tool)
+ matter = tempMatter //We add its value
+ playsound(src.loc, 'sound/machines/click.ogg', 10, TRUE)
+ to_chat(user, span_notice("\The [src] now holds [matter]/[max_matter] [discriptor]."))
+ icon_state = base_icon_state//and set the icon state to the base state
+ return ITEM_INTERACT_SUCCESS
/obj/item/rsf/attack_self(mob/user)
playsound(src.loc, 'sound/effects/pop.ogg', 50, FALSE)
diff --git a/code/game/objects/items/rcd/RWD.dm b/code/game/objects/items/rcd/RWD.dm
index bafbfdc5d8d..0204e12ae2f 100644
--- a/code/game/objects/items/rcd/RWD.dm
+++ b/code/game/objects/items/rcd/RWD.dm
@@ -118,12 +118,11 @@
listeningTo = null
/// for inserting cable into the rwd
-/obj/item/rwd/attackby(obj/item/attacking_item, mob/living/user)
- if(!istype(attacking_item, /obj/item/stack/cable_coil))
- return
- var/obj/item/stack/cable_coil/cable = attacking_item
- add_cable(user, cable)
- return TRUE
+/obj/item/rwd/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/stack/cable_coil))
+ return NONE
+ add_cable(user, tool)
+ return ITEM_INTERACT_SUCCESS
/obj/item/rwd/click_alt(mob/user)
if(!radial_menu)
diff --git a/code/game/objects/items/robot/items/storage.dm b/code/game/objects/items/robot/items/storage.dm
index 759638b6b4e..8e9f1ad6194 100644
--- a/code/game/objects/items/robot/items/storage.dm
+++ b/code/game/objects/items/robot/items/storage.dm
@@ -91,11 +91,11 @@
update_appearance()
return NONE
-/obj/item/borg/apparatus/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
- if(stored)
- item.melee_attack_chain(user, stored, modifiers)
- return
- return ..()
+/obj/item/borg/apparatus/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!stored)
+ return NONE
+ tool.melee_attack_chain(user, stored, modifiers)
+ return ITEM_INTERACT_SUCCESS
/obj/item/borg/apparatus/beaker
name = "beaker storage apparatus"
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 5264bca98bd..dd3fe6a3073 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -165,217 +165,235 @@
chest.cell = temp_cell
return TRUE
-//ADD
-/obj/item/robot_suit/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(W, /obj/item/stack/sheet/iron))
- var/obj/item/stack/sheet/iron/M = W
- if(!l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
- if (!M.use(1))
- to_chat(user, span_warning("You need one sheet of iron to start building ED-209!"))
- return
- var/obj/item/bot_assembly/ed209/assembly = new(drop_location())
- to_chat(user, span_notice("You arm the robot frame."))
- var/held_index = user.is_holding(src)
- qdel(src)
- if (held_index)
- user.put_in_hand(assembly, held_index)
+//ADD <-- what is the purpose of this code comment? is it an abbreviation?
+/obj/item/robot_suit/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(istype(tool, /obj/item/stack/sheet/iron))
+ var/obj/item/stack/sheet/iron/iron_sheet = tool
+ if(l_arm || r_arm || l_leg || r_leg || chest || head)
+ return ITEM_INTERACT_BLOCKING
+ if (!iron_sheet.use(1))
+ to_chat(user, span_warning("You need one sheet of iron to start building ED-209!"))
+ return ITEM_INTERACT_BLOCKING
+ var/obj/item/bot_assembly/ed209/assembly = new(drop_location())
+ to_chat(user, span_notice("You arm the robot frame."))
+ var/held_index = user.is_holding(src)
+ qdel(src)
+ if (held_index)
+ user.put_in_hand(assembly, held_index)
+ return ITEM_INTERACT_SUCCESS
- else if(istype(W, /obj/item/bodypart/leg/left/robot))
+ if(istype(tool, /obj/item/bodypart/leg/left/robot))
if(l_leg)
- return
- if(!user.transferItemToLoc(W, src))
- return
- W.icon_state = initial(W.icon_state)
- W.cut_overlays()
- l_leg = W
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
+ tool.icon_state = initial(tool.icon_state)
+ tool.cut_overlays()
+ l_leg = tool
update_appearance()
+ return ITEM_INTERACT_SUCCESS
- else if(istype(W, /obj/item/bodypart/leg/right/robot))
- if(src.r_leg)
- return
- if(!user.transferItemToLoc(W, src))
- return
- W.icon_state = initial(W.icon_state)
- W.cut_overlays()
- r_leg = W
+ if(istype(tool, /obj/item/bodypart/leg/right/robot))
+ if(r_leg)
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
+ tool.icon_state = initial(tool.icon_state)
+ tool.cut_overlays()
+ r_leg = tool
update_appearance()
+ return ITEM_INTERACT_SUCCESS
- else if(istype(W, /obj/item/bodypart/arm/left/robot))
+ if(istype(tool, /obj/item/bodypart/arm/left/robot))
if(l_arm)
- return
- if(!user.transferItemToLoc(W, src))
- return
- W.icon_state = initial(W.icon_state)
- W.cut_overlays()
- l_arm = W
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
+ tool.icon_state = initial(tool.icon_state)
+ tool.cut_overlays()
+ l_arm = tool
update_appearance()
+ return ITEM_INTERACT_SUCCESS
- else if(istype(W, /obj/item/bodypart/arm/right/robot))
+ if(istype(tool, /obj/item/bodypart/arm/right/robot))
if(r_arm)
- return
- if(!user.transferItemToLoc(W, src))
- return
- W.icon_state = initial(W.icon_state)//in case it is a dismembered robotic limb
- W.cut_overlays()
- r_arm = W
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(tool, src))
+ return ITEM_INTERACT_BLOCKING
+ tool.icon_state = initial(tool.icon_state)//in case it is a dismembered robotic limb
+ tool.cut_overlays()
+ r_arm = tool
update_appearance()
+ return ITEM_INTERACT_SUCCESS
- else if(istype(W, /obj/item/bodypart/chest/robot))
- var/obj/item/bodypart/chest/robot/CH = W
+ if(istype(tool, /obj/item/bodypart/chest/robot))
+ var/obj/item/bodypart/chest/robot/new_chestpiece = tool
if(chest)
- return
- if(CH.wired && CH.cell)
- if(!user.transferItemToLoc(CH, src))
- return
- CH.icon_state = initial(CH.icon_state) //in case it is a dismembered robotic limb
- CH.cut_overlays()
- chest = CH
- update_appearance()
- else if(!CH.wired)
+ return ITEM_INTERACT_BLOCKING
+
+ if(!new_chestpiece.wired)
to_chat(user, span_warning("You need to attach wires to it first!"))
- else
+ return ITEM_INTERACT_BLOCKING
+
+ if(!new_chestpiece.cell)
to_chat(user, span_warning("You need to attach a cell to it first!"))
+ return ITEM_INTERACT_BLOCKING
- else if(istype(W, /obj/item/bodypart/head/robot))
- var/obj/item/bodypart/head/robot/HD = W
- if(locate(/obj/item/organ) in HD)
- to_chat(user, span_warning("There are organs inside [HD]!"))
- return
+ if(!user.transferItemToLoc(new_chestpiece, src))
+ return ITEM_INTERACT_BLOCKING
+
+ new_chestpiece.icon_state = initial(new_chestpiece.icon_state) //in case it is a dismembered robotic limb
+ new_chestpiece.cut_overlays()
+ chest = new_chestpiece
+ update_appearance()
+ return ITEM_INTERACT_SUCCESS
+
+ if(istype(tool, /obj/item/bodypart/head/robot))
+ var/obj/item/bodypart/head/robot/new_headpiece = tool
+ if(locate(/obj/item/organ) in new_headpiece)
+ to_chat(user, span_warning("There are organs inside [new_headpiece]!"))
+ return ITEM_INTERACT_BLOCKING
if(head)
- return
- if(HD.flash2 && HD.flash1)
- if(!user.transferItemToLoc(HD, src))
- return
- HD.icon_state = initial(HD.icon_state)//in case it is a dismembered robotic limb
- HD.cut_overlays()
- head = HD
- update_appearance()
- else
+ return ITEM_INTERACT_BLOCKING
+ if(!new_headpiece.flash2 || !new_headpiece.flash1)
to_chat(user, span_warning("You need to attach a flash to it first!"))
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(new_headpiece, src))
+ return ITEM_INTERACT_BLOCKING
+ new_headpiece.icon_state = initial(new_headpiece.icon_state)//in case it is a dismembered robotic limb
+ new_headpiece.cut_overlays()
+ head = new_headpiece
+ update_appearance()
+ return ITEM_INTERACT_SUCCESS
- else if (W.tool_behaviour == TOOL_MULTITOOL)
- if(check_completion())
- ui_interact(user)
- else
- to_chat(user, span_warning("The endoskeleton must be assembled before debugging can begin!"))
-
- else if(istype(W, /obj/item/mmi))
- var/obj/item/mmi/M = W
- if(check_completion())
- if(!chest.cell)
- to_chat(user, span_warning("The endoskeleton still needs a power cell!"))
- return
- if(!isturf(loc))
- to_chat(user, span_warning("You can't put [M] in, the frame has to be standing on the ground to be perfectly precise!"))
- return
- if(!M.brain_check(user))
- return
-
- var/mob/living/brain/brainmob = M.brainmob
- if(is_banned_from(brainmob.ckey, JOB_CYBORG) || QDELETED(src) || QDELETED(brainmob) || QDELETED(user) || QDELETED(M) || !Adjacent(user))
- if(!QDELETED(M))
- to_chat(user, span_warning("This [M.name] does not seem to fit!"))
- return
- if(!user.temporarilyRemoveItemFromInventory(W))
- return
-
- var/mob/living/silicon/robot/O = new /mob/living/silicon/robot/nocell(get_turf(loc), user)
- if(!O)
- return
- if(M.laws && M.laws.id != DEFAULT_AI_LAWID)
- aisync = FALSE
- lawsync = FALSE
- O.laws = M.laws
- M.laws.associate(O)
-
- O.SetInvisibility(INVISIBILITY_NONE)
- //Transfer debug settings to new mob
- O.custom_name = created_name
- O.locked = panel_locked
- if(!aisync)
- lawsync = FALSE
- O.set_connected_ai(null)
- else
- O.notify_ai(AI_NOTIFICATION_NEW_BORG)
- if(forced_ai)
- O.set_connected_ai(forced_ai)
- if(!lawsync)
- O.lawupdate = FALSE
- if(M.laws.id == DEFAULT_AI_LAWID)
- O.make_laws()
- O.log_current_laws()
-
- brainmob.mind?.remove_antags_for_borging()
- O.job = JOB_CYBORG
-
- O.cell = chest.cell
- chest.cell.forceMove(O)
-
- W.forceMove(O)//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
- QDEL_NULL(O.mmi) //we delete the mmi created by robot/New()
- O.mmi = W //and give the real mmi to the borg.
- O.updatename(brainmob.client)
- // This canonizes that MMI'd cyborgs have memories of their previous life
- brainmob.add_mob_memory(/datum/memory/was_cyborged, protagonist = brainmob.mind, deuteragonist = user)
- brainmob.mind.transfer_to(O)
- playsound(O.loc, 'sound/mobs/non-humanoids/cyborg/liveagain.ogg', 75, TRUE)
-
- if(O.is_antag())
- to_chat(O, span_userdanger("You have been robotized!"))
- to_chat(O, span_danger("You must obey your silicon laws and master AI above all else. Your objectives will consider you to be dead."))
-
- SSblackbox.record_feedback("amount", "cyborg_birth", 1)
- forceMove(O)
- O.robot_suit = src
-
- user.log_message("put the MMI/posibrain of [key_name(M.brainmob)] into a cyborg shell", LOG_GAME)
- M.brainmob.log_message("was put into a cyborg shell by [key_name(user)]", LOG_GAME, log_globally = FALSE)
-
- if(!locomotion)
- O.set_lockcharge(TRUE)
- to_chat(O, span_warning("Error: Servo motors unresponsive."))
-
- else
+ if(istype(tool, /obj/item/mmi))
+ var/obj/item/mmi/potential_brain = tool
+ if(!check_completion())
to_chat(user, span_warning("The MMI must go in after everything else!"))
+ return ITEM_INTERACT_BLOCKING
+ if(!chest.cell)
+ to_chat(user, span_warning("The endoskeleton still needs a power cell!"))
+ return ITEM_INTERACT_BLOCKING
+ if(!isturf(loc))
+ to_chat(user, span_warning("You can't put [potential_brain] in, the frame has to be standing on the ground to be perfectly precise!"))
+ return ITEM_INTERACT_BLOCKING
+ if(!potential_brain.brain_check(user))
+ return ITEM_INTERACT_BLOCKING
- else if(istype(W, /obj/item/borg/upgrade/ai))
- var/obj/item/borg/upgrade/ai/M = W
- if(check_completion())
- if(!isturf(loc))
- to_chat(user, span_warning("You cannot install [M], the frame has to be standing on the ground to be perfectly precise!"))
- return
- if(!user.temporarilyRemoveItemFromInventory(M))
- to_chat(user, span_warning("[M] is stuck to your hand!"))
- return
- qdel(M)
- var/mob/living/silicon/robot/O = new /mob/living/silicon/robot/shell(get_turf(src))
+ var/mob/living/brain/brainmob = potential_brain.brainmob
+ if(is_banned_from(brainmob.ckey, JOB_CYBORG) || QDELETED(src) || QDELETED(brainmob) || QDELETED(user) || QDELETED(potential_brain) || !Adjacent(user))
+ if(!QDELETED(potential_brain))
+ to_chat(user, span_warning("This [potential_brain.name] does not seem to fit!"))
+ return ITEM_INTERACT_BLOCKING
+ if(!user.temporarilyRemoveItemFromInventory(tool))
+ return ITEM_INTERACT_BLOCKING
- if(!aisync)
- lawsync = FALSE
- O.set_connected_ai(null)
- else
- if(forced_ai)
- O.set_connected_ai(forced_ai)
- O.notify_ai(AI_NOTIFICATION_AI_SHELL)
- if(!lawsync)
- O.lawupdate = FALSE
- O.make_laws()
- O.log_current_laws()
+ var/mob/living/silicon/robot/final_product = new /mob/living/silicon/robot/nocell(get_turf(loc), user)
+ if(!final_product)
+ return ITEM_INTERACT_BLOCKING
+ if(potential_brain.laws && potential_brain.laws.id != DEFAULT_AI_LAWID)
+ aisync = FALSE
+ lawsync = FALSE
+ final_product.laws = potential_brain.laws
+ potential_brain.laws.associate(final_product)
- O.cell = chest.cell
- chest.cell.forceMove(O)
+ final_product.SetInvisibility(INVISIBILITY_NONE)
+ //Transfer debug settings to new mob
+ final_product.custom_name = created_name
+ final_product.locked = panel_locked
+ if(!aisync)
+ lawsync = FALSE
+ final_product.set_connected_ai(null)
+ else
+ final_product.notify_ai(AI_NOTIFICATION_NEW_BORG)
+ if(forced_ai)
+ final_product.set_connected_ai(forced_ai)
+ if(!lawsync)
+ final_product.lawupdate = FALSE
+ if(potential_brain.laws.id == DEFAULT_AI_LAWID)
+ final_product.make_laws()
+ final_product.log_current_laws()
- O.locked = panel_locked
- O.job = JOB_CYBORG
- forceMove(O)
- O.robot_suit = src
- if(!locomotion)
- O.set_lockcharge(TRUE)
+ brainmob.mind?.remove_antags_for_borging()
+ final_product.job = JOB_CYBORG
- else if(IS_WRITING_UTENSIL(W))
+ final_product.cell = chest.cell
+ chest.cell.forceMove(final_product)
+
+ tool.forceMove(final_product)//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
+ QDEL_NULL(final_product.mmi) //we delete the mmi created by robot/New()
+ final_product.mmi = tool //and give the real mmi to the borg.
+ final_product.updatename(brainmob.client)
+ // This canonizes that MMI'd cyborgs have memories of their previous life
+ brainmob.add_mob_memory(/datum/memory/was_cyborged, protagonist = brainmob.mind, deuteragonist = user)
+ brainmob.mind.transfer_to(final_product)
+ playsound(final_product.loc, 'sound/mobs/non-humanoids/cyborg/liveagain.ogg', 75, TRUE)
+
+ if(final_product.is_antag())
+ to_chat(final_product, span_userdanger("You have been robotized!"))
+ to_chat(final_product, span_danger("You must obey your silicon laws and master AI above all else. Your objectives will consider you to be dead."))
+
+ SSblackbox.record_feedback("amount", "cyborg_birth", 1)
+ forceMove(final_product)
+ final_product.robot_suit = src
+
+ user.log_message("put the MMI/posibrain of [key_name(brainmob)] into a cyborg shell", LOG_GAME)
+ brainmob.log_message("was put into a cyborg shell by [key_name(user)]", LOG_GAME, log_globally = FALSE)
+
+ if(!locomotion)
+ final_product.set_lockcharge(TRUE)
+ to_chat(final_product, span_warning("Error: Servo motors unresponsive."))
+ return ITEM_INTERACT_SUCCESS
+
+
+ if(istype(tool, /obj/item/borg/upgrade/ai))
+ var/obj/item/borg/upgrade/ai/boris_module = tool
+ if(!check_completion())
+ return ITEM_INTERACT_BLOCKING
+ if(!isturf(loc))
+ to_chat(user, span_warning("You cannot install [boris_module], the frame has to be standing on the ground to be perfectly precise!"))
+ return ITEM_INTERACT_BLOCKING
+ if(!user.temporarilyRemoveItemFromInventory(boris_module))
+ to_chat(user, span_warning("[boris_module] is stuck to your hand!"))
+ return ITEM_INTERACT_BLOCKING
+ qdel(boris_module)
+ var/mob/living/silicon/robot/final_product = new /mob/living/silicon/robot/shell(get_turf(src))
+
+ if(!aisync)
+ lawsync = FALSE
+ final_product.set_connected_ai(null)
+ else
+ if(forced_ai)
+ final_product.set_connected_ai(forced_ai)
+ final_product.notify_ai(AI_NOTIFICATION_AI_SHELL)
+ if(!lawsync)
+ final_product.lawupdate = FALSE
+ final_product.make_laws()
+ final_product.log_current_laws()
+
+ final_product.cell = chest.cell
+ chest.cell.forceMove(final_product)
+
+ final_product.locked = panel_locked
+ final_product.job = JOB_CYBORG
+ forceMove(final_product)
+ final_product.robot_suit = src
+ if(!locomotion)
+ final_product.set_lockcharge(TRUE)
+ return ITEM_INTERACT_SUCCESS
+
+ if(IS_WRITING_UTENSIL(tool))
to_chat(user, span_warning("You need to use a multitool to name [src]!"))
- else
- return ..()
+ return ITEM_INTERACT_BLOCKING
+
+ return NONE
+
+/obj/item/robot_suit/multitool_act(mob/living/user, obj/item/tool)
+ if(!check_completion())
+ to_chat(user, span_warning("The endoskeleton must be assembled before debugging can begin!"))
+ return ITEM_INTERACT_SKIP_TO_ATTACK
+ ui_interact(user)
+ return ITEM_INTERACT_SUCCESS
/obj/item/robot_suit/ui_status(mob/user, datum/ui_state/state)
if(isobserver(user))
diff --git a/code/game/objects/items/sharpener.dm b/code/game/objects/items/sharpener.dm
index f01ca917f8c..1da204615af 100644
--- a/code/game/objects/items/sharpener.dm
+++ b/code/game/objects/items/sharpener.dm
@@ -23,45 +23,46 @@
///If TRUE, the whetstone will only sharpen already sharp items
var/requires_sharpness = TRUE
-/obj/item/sharpener/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/sharpener/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(uses == 0)
to_chat(user, span_warning("The sharpening block is too worn to use again!"))
- return
- if(I.force >= max || I.throwforce >= max) //So the whetstone never reduces force or throw_force
- to_chat(user, span_warning("[I] is much too powerful to sharpen further!"))
- return
- if(requires_sharpness && !I.get_sharpness())
+ return ITEM_INTERACT_BLOCKING
+ if(tool.force >= max || tool.throwforce >= max) //So the whetstone never reduces force or throw_force
+ to_chat(user, span_warning("[tool] is much too powerful to sharpen further!"))
+ return ITEM_INTERACT_BLOCKING
+ if(requires_sharpness && !tool.get_sharpness())
to_chat(user, span_warning("You can only sharpen items that are already sharp, such as knives!"))
- return
- if(is_type_in_list(I, list(/obj/item/melee/energy, /obj/item/dualsaber))) //You can't sharpen the photons in energy meelee weapons
- to_chat(user, span_warning("You don't think \the [I] will be the thing getting modified if you use it on \the [src]!"))
- return
+ return ITEM_INTERACT_BLOCKING
+ if(is_type_in_list(tool, list(/obj/item/melee/energy, /obj/item/dualsaber))) //You can't sharpen the photons in energy meelee weapons
+ to_chat(user, span_warning("You don't think \the [tool] will be the thing getting modified if you use it on \the [src]!"))
+ return ITEM_INTERACT_BLOCKING
//This block is used to check more things if the item has a relevant component.
- var/signal_out = SEND_SIGNAL(I, COMSIG_ITEM_SHARPEN_ACT, increment, max) //Stores the bitflags returned by SEND_SIGNAL
+ var/signal_out = SEND_SIGNAL(tool, COMSIG_ITEM_SHARPEN_ACT, increment, max) //Stores the bitflags returned by SEND_SIGNAL
if(signal_out & COMPONENT_BLOCK_SHARPEN_MAXED) //If the item's components enforce more limits on maximum power from sharpening, we fail
- to_chat(user, span_warning("[I] is much too powerful to sharpen further!"))
- return
+ to_chat(user, span_warning("[tool] is much too powerful to sharpen further!"))
+ return ITEM_INTERACT_BLOCKING
if(signal_out & COMPONENT_BLOCK_SHARPEN_BLOCKED)
- to_chat(user, span_warning("[I] is not able to be sharpened right now!"))
- return
- if((signal_out & COMPONENT_BLOCK_SHARPEN_ALREADY) || (I.force > initial(I.force) && !signal_out)) //No sharpening stuff twice
- to_chat(user, span_warning("[I] has already been refined before. It cannot be sharpened further!"))
- return
+ to_chat(user, span_warning("[tool] is not able to be sharpened right now!"))
+ return ITEM_INTERACT_BLOCKING
+ if((signal_out & COMPONENT_BLOCK_SHARPEN_ALREADY) || (tool.force > initial(tool.force) && !signal_out)) //No sharpening stuff twice
+ to_chat(user, span_warning("[tool] has already been refined before. It cannot be sharpened further!"))
+ return ITEM_INTERACT_BLOCKING
if(!(signal_out & COMPONENT_BLOCK_SHARPEN_APPLIED)) //If the item has a relevant component and COMPONENT_BLOCK_SHARPEN_APPLIED is returned, the item only gets the throw force increase
- I.force = clamp(I.force + increment, 0, max)
- I.wound_bonus = I.wound_bonus + increment //wound_bonus has no cap
- user.visible_message(span_notice("[user] sharpens [I] with [src]!"), span_notice("You sharpen [I], making it much more deadly than before."))
+ tool.force = clamp(tool.force + increment, 0, max)
+ tool.wound_bonus = tool.wound_bonus + increment //wound_bonus has no cap
+ user.visible_message(span_notice("[user] sharpens [tool] with [src]!"), span_notice("You sharpen [tool], making it much more deadly than before."))
playsound(src, 'sound/items/unsheath.ogg', 25, TRUE)
if(!(signal_out & COMPONENT_BLOCK_SHARPEN_SHARPNESS))
- I.sharpness = SHARP_EDGED //When you whetstone something, it becomes an edged weapon, even if it was previously dull or pointy
- I.throwforce = clamp(I.throwforce + increment, 0, max)
- I.name = "[prefix] [I.name]" //This adds a prefix and a space to the item's name regardless of what the prefix is
+ tool.sharpness = SHARP_EDGED //When you whetstone something, it becomes an edged weapon, even if it was previously dull or pointy
+ tool.throwforce = clamp(tool.throwforce + increment, 0, max)
+ tool.name = "[prefix] [tool.name]" //This adds a prefix and a space to the item's name regardless of what the prefix is
desc = "[desc] At least, it used to."
uses-- //this doesn't cause issues because we check if uses == 0 earlier in this proc
if(uses == 0)
name = "worn out [name]" //whetstone becomes used whetstone
update_appearance()
+ return ITEM_INTERACT_SUCCESS
/obj/item/sharpener/update_name()
name = "[!uses ? "worn out " : null][initial(name)]"
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index 1009aa894ef..55e67cc13bc 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -49,37 +49,42 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
. = ..()
. += GLOB.glass_recipes
-/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/stack/sheet/glass/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
add_fingerprint(user)
- if(istype(W, /obj/item/lightreplacer))
- var/obj/item/lightreplacer/lightreplacer = W
- lightreplacer.attackby(src, user)
- if(istype(W, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/CC = W
- if (get_amount() < 1 || CC.get_amount() < 5)
+ if(istype(tool, /obj/item/lightreplacer))
+ var/obj/item/lightreplacer/lightreplacer = tool
+ lightreplacer.item_interaction(user, src, modifiers)
+ return ITEM_INTERACT_SUCCESS
+
+ if(istype(tool, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/coil = tool
+ if (get_amount() < 1 || coil.get_amount() < 5)
to_chat(user, span_warning("You need five lengths of coil and one sheet of glass to make wired glass!"))
- return
- CC.use(5)
+ return ITEM_INTERACT_BLOCKING
+ coil.use(5)
use(1)
to_chat(user, span_notice("You attach wire to \the [src]."))
var/obj/item/stack/light_w/new_tile = new(user.loc)
if (!QDELETED(new_tile))
new_tile.add_fingerprint(user)
- return
- if(istype(W, /obj/item/stack/rods))
- var/obj/item/stack/rods/V = W
- if (V.get_amount() >= 1 && get_amount() >= 1)
- var/obj/item/stack/sheet/rglass/RG = new (get_turf(user))
- if(!QDELETED(RG))
- RG.add_fingerprint(user)
- var/replace = user.get_inactive_held_item() == src
- V.use(1)
- use(1)
- if(QDELETED(src) && replace && !QDELETED(RG))
- user.put_in_hands(RG)
- else
+ return ITEM_INTERACT_SUCCESS
+
+ if(istype(tool, /obj/item/stack/rods))
+ var/obj/item/stack/rods/rods = tool
+ if (rods.get_amount() < 1 || get_amount() < 1) // the hell kind of check is this, how would this happen
to_chat(user, span_warning("You need one rod and one sheet of glass to make reinforced glass!"))
- return
+ return ITEM_INTERACT_BLOCKING
+
+ var/obj/item/stack/sheet/rglass/new_glass = new (get_turf(user))
+ if(!QDELETED(new_glass))
+ new_glass.add_fingerprint(user)
+ var/replace = user.get_inactive_held_item() == src
+ rods.use(1)
+ use(1)
+ if(QDELETED(src) && replace && !QDELETED(new_glass))
+ user.put_in_hands(new_glass)
+ return ITEM_INTERACT_SUCCESS
+
return ..()
GLOBAL_LIST_INIT(pglass_recipes, list ( \
@@ -116,26 +121,28 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \
. = ..()
. += GLOB.pglass_recipes
-/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/stack/sheet/plasmaglass/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
add_fingerprint(user)
-
- if(istype(W, /obj/item/stack/rods))
- var/obj/item/stack/rods/V = W
- if (V.get_amount() >= 1 && get_amount() >= 1)
- var/obj/item/stack/sheet/plasmarglass/RG = new (get_turf(user))
- if (!QDELETED(RG))
- RG.add_fingerprint(user)
- var/replace = user.get_inactive_held_item() == src
- V.use(1)
- use(1)
- if(QDELETED(src) && replace)
- user.put_in_hands(RG)
- else
- to_chat(user, span_warning("You need one rod and one sheet of plasma glass to make reinforced plasma glass!"))
- return
- else
+ if(!istype(tool, /obj/item/stack/rods))
return ..()
+ var/obj/item/stack/rods/rods = tool
+ if (rods.get_amount() < 1 || get_amount() < 1)
+ to_chat(user, span_warning("You need one rod and one sheet of plasma glass to make reinforced plasma glass!"))
+ return ITEM_INTERACT_BLOCKING
+
+ var/obj/item/stack/sheet/plasmarglass/RG = new (get_turf(user))
+ if (!QDELETED(RG))
+ RG.add_fingerprint(user)
+ var/replace = user.get_inactive_held_item() == src
+ rods.use(1)
+ use(1)
+ if(QDELETED(src) && replace)
+ user.put_in_hands(RG)
+ return ITEM_INTERACT_SUCCESS
+
+
+
/*
* Reinforced glass sheets
*/
@@ -174,9 +181,9 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
fire = 70
acid = 100
-/obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/stack/sheet/rglass/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
add_fingerprint(user)
- ..()
+ . = ..()
/obj/item/stack/sheet/rglass/get_main_recipes()
. = ..()
diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm
index 83b202bc911..c2e769c7f55 100644
--- a/code/game/objects/items/stacks/sheets/leather.dm
+++ b/code/game/objects/items/stacks/sheets/leather.dm
@@ -379,17 +379,17 @@ GLOBAL_LIST_INIT(bear_pelt_recipes, list ( \
. += GLOB.bear_pelt_recipes
//Step one - dehairing.
-
-/obj/item/stack/sheet/animalhide/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(W.get_sharpness())
- playsound(loc, 'sound/items/weapons/slice.ogg', 50, TRUE, -1)
- user.visible_message(span_notice("[user] starts cutting hair off \the [src]."), span_notice("You start cutting the hair off \the [src]..."), span_hear("You hear the sound of a knife rubbing against flesh."))
- if(do_after(user, 5 SECONDS, target = src))
- to_chat(user, span_notice("You cut the hair from [src.name]."))
- new /obj/item/stack/sheet/hairlesshide(user.drop_location(), amount)
- use(amount)
- else
+/obj/item/stack/sheet/animalhide/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!tool.get_sharpness())
return ..()
+ playsound(loc, 'sound/items/weapons/slice.ogg', 50, TRUE, -1)
+ user.visible_message(span_notice("[user] starts cutting hair off \the [src]."), span_notice("You start cutting the hair off \the [src]..."), span_hear("You hear the sound of a knife rubbing against flesh."))
+ if(!do_after(user, 5 SECONDS, target = src))
+ return ITEM_INTERACT_BLOCKING
+ to_chat(user, span_notice("You cut the hair from [src.name]."))
+ new /obj/item/stack/sheet/hairlesshide(user.drop_location(), amount)
+ use(amount)
+ return ITEM_INTERACT_SUCCESS
/obj/item/stack/sheet/animalhide/examine(mob/user)
. = ..()
diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm
index 4d06e8fb3d1..7f4e589f034 100644
--- a/code/game/objects/items/stacks/sheets/light.dm
+++ b/code/game/objects/items/stacks/sheets/light.dm
@@ -21,19 +21,20 @@
. = ..()
. += span_warning("\The [src] looks unfinished, add iron to complete it.")
-/obj/item/stack/light_w/attackby(obj/item/O, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(O, /obj/item/stack/sheet/iron))
- var/obj/item/stack/sheet/iron/M = O
- if (M.use(1))
- var/obj/item/L = new /obj/item/stack/tile/light(user.drop_location())
- to_chat(user, span_notice("You make a light tile."))
- if (!QDELETED(L))
- L.add_fingerprint(user)
- use(1)
- else
- to_chat(user, span_warning("You need one iron sheet to finish the light tile!"))
- else
+/obj/item/stack/light_w/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/stack/sheet/iron))
return ..()
+ var/obj/item/stack/sheet/iron/steel = tool
+ if(!steel.use(1))
+ to_chat(user, span_warning("You need one iron sheet to finish the light tile!"))
+ return ITEM_INTERACT_BLOCKING
+
+ var/obj/item/stack/tile/light/finished_tiles = new(user.drop_location())
+ to_chat(user, span_notice("You make a light tile."))
+ if(!QDELETED(finished_tiles))
+ finished_tiles.add_fingerprint(user)
+ use(1)
+ return ITEM_INTERACT_SUCCESS
/obj/item/stack/light_w/wirecutter_act(mob/living/user, obj/item/I)
. = ..()
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 8bd0b2b9ad8..0d05b853a9e 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -85,17 +85,17 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
icon_state = "sandbag"
w_class = WEIGHT_CLASS_TINY
-/obj/item/emptysandbag/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(W, /obj/item/stack/ore/glass))
- var/obj/item/stack/ore/glass/G = W
- to_chat(user, span_notice("You fill the sandbag."))
- var/obj/item/stack/sheet/mineral/sandbags/I = new (drop_location())
- qdel(src)
- if (Adjacent(user) && !issilicon(user))
- user.put_in_hands(I)
- G.use(1)
- else
- return ..()
+/obj/item/emptysandbag/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/stack/ore/glass))
+ return NONE
+ var/obj/item/stack/ore/glass/sand = tool
+ to_chat(user, span_notice("You fill the sandbag."))
+ var/obj/item/stack/sheet/mineral/sandbags/filled_bag = new (drop_location())
+ qdel(src)
+ if(Adjacent(user) && !issilicon(user))
+ user.put_in_hands(filled_bag)
+ sand.use(1)
+ return ITEM_INTERACT_SUCCESS
/*
* Diamond
@@ -316,25 +316,28 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
. = ..()
. += GLOB.titanium_recipes
-/obj/item/stack/sheet/mineral/titanium/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/stack/sheet/mineral/titanium/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
add_fingerprint(user)
- if(istype(W, /obj/item/stack/rods))
- var/obj/item/stack/rods/old_rods = W
- if(old_rods.merge_type != /obj/item/stack/rods)
- to_chat(user, span_warning("You can't craft shuttle frame rods with this type of rod!"))
- if (old_rods.get_amount() >= 5 && get_amount() >= 1)
- var/obj/item/stack/rods/shuttle/five/new_rods = new (get_turf(user))
- if(!QDELETED(new_rods))
- new_rods.add_fingerprint(user)
- var/replace = user.get_inactive_held_item() == src
- old_rods.use(5)
- use(1)
- if(QDELETED(src) && replace && !QDELETED(new_rods))
- user.put_in_hands(new_rods)
- else
- to_chat(user, span_warning("You need five rods and one sheet of titanium to make shuttle frame rods!"))
- return
- return ..()
+ if(!istype(tool, /obj/item/stack/rods))
+ return ..()
+ var/obj/item/stack/rods/old_rods = tool
+ if(old_rods.merge_type != /obj/item/stack/rods)
+ to_chat(user, span_warning("You can't craft shuttle frame rods with this type of rod!"))
+ return ITEM_INTERACT_BLOCKING
+
+ if (old_rods.get_amount() < 5 && get_amount() < 1)
+ to_chat(user, span_warning("You need five rods and one sheet of titanium to make shuttle frame rods!"))
+ return ITEM_INTERACT_BLOCKING
+
+ var/obj/item/stack/rods/shuttle/five/new_rods = new (get_turf(user))
+ if(!QDELETED(new_rods))
+ new_rods.add_fingerprint(user)
+ var/replace = user.get_inactive_held_item() == src
+ old_rods.use(5)
+ use(1)
+ if(QDELETED(src) && replace && !QDELETED(new_rods))
+ user.put_in_hands(new_rods)
+ return ITEM_INTERACT_SUCCESS
/obj/item/stack/sheet/mineral/titanium/fifty
amount = 50
@@ -498,15 +501,15 @@ GLOBAL_LIST_INIT(abductor_recipes, list ( \
/obj/item/stack/sheet/mineral/coal/grind_results()
return list(/datum/reagent/carbon = 20)
-/obj/item/stack/sheet/mineral/coal/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(W.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) //If the temperature of the object is hot enough to start a fire, then ignite
- var/turf/T = get_turf(src)
- message_admins("Coal ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(T)]")
- user.log_message("ignited coal", LOG_GAME)
- fire_act(W.get_temperature())
- return TRUE
- else
+/obj/item/stack/sheet/mineral/coal/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(tool.get_temperature() < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) //If the temperature of the object is hot enough to start a fire, then ignite
return ..()
+ var/turf/jumpturf = get_turf(src)
+ message_admins("Coal ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(jumpturf)]")
+ user.log_message("ignited coal", LOG_GAME)
+ fire_act(tool.get_temperature())
+ return ITEM_INTERACT_SUCCESS
+
/obj/item/stack/sheet/mineral/coal/fire_act(exposed_temperature, exposed_volume)
atmos_spawn_air("[GAS_CO2]=[amount*10];[TURF_TEMPERATURE(exposed_temperature)]")
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 8ec2a97520a..53f8301a2c3 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -745,22 +745,25 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
/obj/item/stack/sheet/cardboard/fifty
amount = 50
-/obj/item/stack/sheet/cardboard/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(I, /obj/item/stamp/clown) && !istype(loc, /obj/item/storage))
+/obj/item/stack/sheet/cardboard/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(istype(tool, /obj/item/stamp/clown) && !istype(loc, /obj/item/storage))
var/atom/droploc = drop_location()
- if(use(1))
- playsound(I, 'sound/items/bikehorn.ogg', 50, TRUE, -1)
- to_chat(user, span_notice("You stamp the cardboard! It's a clown box! Honk!"))
- if (amount >= 0)
- new/obj/item/storage/box/clown(droploc) //bugfix
- if(istype(I, /obj/item/stamp/chameleon) && !istype(loc, /obj/item/storage))
+ if(!use(1))
+ return ITEM_INTERACT_BLOCKING
+ playsound(tool, 'sound/items/bikehorn.ogg', 50, TRUE, -1)
+ to_chat(user, span_notice("You stamp the cardboard! It's a clown box! Honk!"))
+ new /obj/item/storage/box/clown(droploc) //bugfix
+ return ITEM_INTERACT_SUCCESS
+
+ if(istype(tool, /obj/item/stamp/chameleon) && !istype(loc, /obj/item/storage))
var/atom/droploc = drop_location()
- if(use(1))
- to_chat(user, span_notice("You stamp the cardboard in a sinister way."))
- if (amount >= 0)
- new/obj/item/storage/box/syndie_kit(droploc)
- else
- . = ..()
+ if(!use(1))
+ return ITEM_INTERACT_BLOCKING
+ to_chat(user, span_notice("You stamp the cardboard in a sinister way."))
+ new /obj/item/storage/box/syndie_kit(droploc)
+ return ITEM_INTERACT_SUCCESS
+
+ return ..()
/*
* Bronze
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index a7b365b3e29..c49c1784e11 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -792,13 +792,14 @@
user.put_in_hands(new_stack, merge_stacks = FALSE)
return new_stack
-/obj/item/stack/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(can_merge(W, inhand = TRUE))
- var/obj/item/stack/S = W
- if(merge(S))
- to_chat(user, span_notice("Your [S.name] stack now contains [S.get_amount()] [S.singular_name]\s."))
- else
- . = ..()
+/obj/item/stack/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!can_merge(tool, inhand = TRUE))
+ return NONE
+ var/obj/item/stack/overtaking_stack = tool
+ if(!merge(overtaking_stack))
+ return ITEM_INTERACT_BLOCKING
+ to_chat(user, span_notice("Your [overtaking_stack.name] stack now contains [overtaking_stack.get_amount()] [overtaking_stack.singular_name]\s."))
+ return ITEM_INTERACT_SUCCESS
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
add_blood_DNA(GET_ATOM_BLOOD_DNA(from))
diff --git a/code/game/objects/items/stacks/tiles/light.dm b/code/game/objects/items/stacks/tiles/light.dm
index 651cf36ac1a..56b0a0653a8 100644
--- a/code/game/objects/items/stacks/tiles/light.dm
+++ b/code/game/objects/items/stacks/tiles/light.dm
@@ -11,15 +11,14 @@
mats_per_unit = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 1.05, /datum/material/glass = SHEET_MATERIAL_AMOUNT * 1.05)
var/state = 0
-/obj/item/stack/tile/light/attackby(obj/item/O, mob/user, list/modifiers, list/attack_modifiers)
- if(O.tool_behaviour == TOOL_CROWBAR)
- new/obj/item/stack/sheet/iron(user.loc)
- amount--
- new/obj/item/stack/light_w(user.loc)
- if(amount <= 0)
- qdel(src)
- else
- return ..()
+/obj/item/stack/tile/light/crowbar_act(mob/living/user, obj/item/tool)
+ new/obj/item/stack/sheet/iron(user.loc)
+ amount--
+ new/obj/item/stack/light_w(user.loc)
+ if(amount <= 0)
+ qdel(src)
+ return ITEM_INTERACT_SUCCESS
+
/obj/item/stack/tile/light/place_tile(turf/open/target_plating, mob/user)
. = ..()
diff --git a/code/game/objects/items/stacks/tiles/tile_mineral.dm b/code/game/objects/items/stacks/tiles/tile_mineral.dm
index 67a905b4334..6650528d012 100644
--- a/code/game/objects/items/stacks/tiles/tile_mineral.dm
+++ b/code/game/objects/items/stacks/tiles/tile_mineral.dm
@@ -2,27 +2,26 @@
/// Determines what stack is gotten out of us when welded.
var/mineralType = null
-/obj/item/stack/tile/mineral/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(W.tool_behaviour == TOOL_WELDER)
- if(get_amount() < 4)
- to_chat(user, span_warning("You need at least four tiles to do this!"))
- return
- if(!mineralType)
- to_chat(user, span_warning("You can not reform this!"))
- stack_trace("A mineral tile of type [type] doesn't have its mineralType set.")
- return
- if(W.use_tool(src, user, 0, volume=40))
- var/sheet_type = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
- var/obj/item/stack/sheet/mineral/new_item = new sheet_type(user.loc)
- user.visible_message(span_notice("[user] shaped [src] into [new_item] with [W]."), \
- span_notice("You shaped [src] into [new_item] with [W]."), \
- span_hear("You hear welding."))
- var/holding = user.is_holding(src)
- use(4)
- if(holding && QDELETED(src))
- user.put_in_hands(new_item)
- else
- return ..()
+/obj/item/stack/tile/mineral/welder_act(mob/living/user, obj/item/tool)
+ if(get_amount() < 4)
+ to_chat(user, span_warning("You need at least four tiles to do this!"))
+ return ITEM_INTERACT_BLOCKING
+ if(!mineralType)
+ to_chat(user, span_warning("You can not reform this!"))
+ stack_trace("A mineral tile of type [type] doesn't have its mineralType set.")
+ return ITEM_INTERACT_BLOCKING
+ if(!tool.use_tool(src, user, 0, volume=40))
+ return ITEM_INTERACT_BLOCKING
+ var/sheet_type = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
+ var/obj/item/stack/sheet/mineral/new_item = new sheet_type(user.loc)
+ user.visible_message(span_notice("[user] shaped [src] into [new_item] with [tool]."), \
+ span_notice("You shaped [src] into [new_item] with [tool]."), \
+ span_hear("You hear welding."))
+ var/holding = user.is_holding(src)
+ use(4)
+ if(holding && QDELETED(src))
+ user.put_in_hands(new_item)
+ return ITEM_INTERACT_SUCCESS
/obj/item/stack/tile/mineral/plasma
name = "plasma tile"
diff --git a/code/game/objects/items/tail_pin.dm b/code/game/objects/items/tail_pin.dm
index 8b6aa245b3c..32a4d164bdc 100644
--- a/code/game/objects/items/tail_pin.dm
+++ b/code/game/objects/items/tail_pin.dm
@@ -35,16 +35,15 @@
MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/party_game, 32)
-/obj/structure/sign/poster/party_game/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
- . = ..()
- if(!istype(attacking_item, /obj/item/tail_pin))//We're using the same trick that tables use for placing objects x and y onto the click location.
- return
+/obj/structure/sign/poster/party_game/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/tail_pin))//We're using the same trick that tables use for placing objects x and y onto the click location.
+ return NONE
var/x_offset = 0
var/y_offset = 0
if(LAZYACCESS(modifiers, ICON_X) && LAZYACCESS(modifiers, ICON_Y))
x_offset = clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X/2), ICON_SIZE_X/2)
y_offset = clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y/2), ICON_SIZE_Y/2)
- if(!user.transfer_item_to_turf(attacking_item, drop_location(), x_offset, y_offset, silent = FALSE))
- return
- return TRUE
+ if(!user.transfer_item_to_turf(tool, drop_location(), x_offset, y_offset, silent = FALSE))
+ return ITEM_INTERACT_BLOCKING
+ return ITEM_INTERACT_SUCCESS
diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm
index 11ce2b69479..9bc4796162b 100644
--- a/code/game/objects/items/tanks/tank_types.dm
+++ b/code/game/objects/items/tanks/tank_types.dm
@@ -101,18 +101,18 @@
/obj/item/tank/internals/plasma/populate_gas()
air_contents.set_gas(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
-/obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(W, /obj/item/flamethrower))
- var/obj/item/flamethrower/F = W
- if ((!F.status) || (F.ptank))
- return
- if(!user.transferItemToLoc(src, F))
- return
- src.master = F
- F.ptank = src
- F.update_appearance()
- else
+/obj/item/tank/internals/plasma/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/flamethrower))
return ..()
+ var/obj/item/flamethrower/spewer = tool
+ if (spewer.status || spewer.ptank)
+ return ITEM_INTERACT_BLOCKING
+ if(!user.transferItemToLoc(src, spewer))
+ return ITEM_INTERACT_BLOCKING
+ master = spewer // does master even do anything anymore?
+ spewer.ptank = src
+ spewer.update_appearance()
+ return ITEM_INTERACT_SUCCESS
/obj/item/tank/internals/plasma/full/populate_gas()
air_contents.set_gas(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm
index a878e89e975..78d6983292c 100644
--- a/code/game/objects/items/tanks/tanks.dm
+++ b/code/game/objects/items/tanks/tanks.dm
@@ -199,15 +199,15 @@
to_chat(user, span_warning("There isn't enough pressure in [src] to commit suicide with..."))
return SHAME
-/obj/item/tank/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/tank/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
add_fingerprint(user)
- if(istype(attacking_item, /obj/item/assembly_holder))
- if(tank_assembly)
- balloon_alert(user, "something already attached!")
- return ITEM_INTERACT_BLOCKING
- bomb_assemble(attacking_item, user)
- return ITEM_INTERACT_SUCCESS
- return ..()
+ if(!istype(tool, /obj/item/assembly_holder))
+ return NONE
+ if(tank_assembly)
+ balloon_alert(user, "something already attached!")
+ return ITEM_INTERACT_BLOCKING
+ bomb_assemble(tool, user)
+ return ITEM_INTERACT_SUCCESS
/obj/item/tank/wrench_act(mob/living/user, obj/item/tool)
if(tank_assembly)
diff --git a/code/game/objects/items/toy_mechs.dm b/code/game/objects/items/toy_mechs.dm
index cf8b1f34128..77970efac14 100644
--- a/code/game/objects/items/toy_mechs.dm
+++ b/code/game/objects/items/toy_mechs.dm
@@ -144,12 +144,12 @@
/**
* If you attack a mech with a mech, initiate combat between them
*/
-/obj/item/toy/mecha/attackby(obj/item/user_toy, mob/living/user)
- if(istype(user_toy, /obj/item/toy/mecha))
- var/obj/item/toy/mecha/P = user_toy
- if(check_battle_start(user, P))
- mecha_brawl(P, user)
- ..()
+/obj/item/toy/mecha/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/toy/mecha))
+ return NONE
+ var/obj/item/toy/mecha/challenger = tool
+ if(check_battle_start(user, challenger))
+ mecha_brawl(challenger, user)
/**
* Attack is called from the user's toy, aimed at target(another human), checking for target's toy.
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 771bacc5a8f..8cc5d16adf6 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -78,22 +78,27 @@
return ITEM_INTERACT_SUCCESS
return ITEM_INTERACT_BLOCKING
-/obj/item/toy/waterballoon/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(I, /obj/item/reagent_containers/cup))
- if(I.reagents)
- if(I.reagents.total_volume <= 0)
- to_chat(user, span_warning("[I] is empty."))
- else if(reagents.total_volume >= 10)
- to_chat(user, span_warning("[src] is full."))
- else
- desc = "A translucent balloon with some form of liquid sloshing around in it."
- to_chat(user, span_notice("You fill the balloon with the contents of [I]."))
- I.reagents.trans_to(src, 10, transferred_by = user)
- update_appearance()
- else if(I.get_sharpness())
+/obj/item/toy/waterballoon/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(istype(tool, /obj/item/reagent_containers/cup) && tool.reagents)
+ if(tool.reagents.total_volume <= 0)
+ to_chat(user, span_warning("[tool] is empty."))
+ return ITEM_INTERACT_BLOCKING
+
+ if(reagents.total_volume >= 10)
+ to_chat(user, span_warning("[src] is full."))
+ return ITEM_INTERACT_BLOCKING
+
+ desc = "A translucent balloon with some form of liquid sloshing around in it."
+ to_chat(user, span_notice("You fill the balloon with the contents of [tool]."))
+ tool.reagents.trans_to(src, 10, transferred_by = user)
+ update_appearance()
+ return ITEM_INTERACT_SUCCESS
+
+ if(tool.get_sharpness())
balloon_burst()
- else
- return ..()
+ return ITEM_INTERACT_SUCCESS
+
+ return NONE
/obj/item/toy/waterballoon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) //was it caught by a mob?
@@ -167,17 +172,18 @@
)
-/obj/item/toy/balloon/long/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
- if(!istype(attacking_item, /obj/item/toy/balloon/long) || !HAS_TRAIT(user, TRAIT_BALLOON_SUTRA))
+/obj/item/toy/balloon/long/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/toy/balloon/long) || !HAS_TRAIT(user, TRAIT_BALLOON_SUTRA))
return ..()
- var/obj/item/toy/balloon/long/hit_by = attacking_item
+ var/obj/item/toy/balloon/long/hit_by = tool
if(hit_by.current_color == current_color)
to_chat(user, span_warning("You must use balloons of different colours to do that!"))
- return ..()
- visible_message(
+ return ITEM_INTERACT_BLOCKING
+ user.visible_message(
span_notice("[user.name] starts contorting up a balloon animal!"),
- blind_message = span_hear("You hear balloons being contorted."),
+ span_notice("You start twisting together a balloon animal!"),
+ span_hear("You hear balloons being contorted."),
vision_distance = 3,
ignored_mobs = user,
)
@@ -188,13 +194,13 @@
break
qdel(hit_by)
qdel(src)
- return TRUE
+ return ITEM_INTERACT_SUCCESS
-/obj/item/toy/balloon/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
- if(istype(I, /obj/item/ammo_casing/foam_dart) && ismonkey(user))
- pop_balloon(monkey_pop = TRUE)
- else
- return ..()
+/obj/item/toy/balloon/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/ammo_casing/foam_dart) || !ismonkey(user))
+ return NONE
+ pop_balloon(monkey_pop = TRUE)
+ return ITEM_INTERACT_SUCCESS
/obj/item/toy/balloon/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
var/mob/thrower = throwingdatum?.get_thrower()
@@ -515,39 +521,39 @@
. = ..()
. += "There [bullets == 1 ? "is" : "are"] [bullets] cap\s left."
-/obj/item/toy/gun/attackby(obj/item/toy/ammo/gun/A, mob/user, list/modifiers, list/attack_modifiers)
+/obj/item/toy/gun/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
- if(istype(A, /obj/item/toy/ammo/gun))
- if (src.bullets >= 7)
- to_chat(user, span_warning("It's already fully loaded!"))
- return 1
- if (A.amount_left <= 0)
- to_chat(user, span_warning("There are no more caps!"))
- return 1
- if (A.amount_left < (7 - src.bullets))
- src.bullets += A.amount_left
- to_chat(user, span_notice("You reload [A.amount_left] cap\s."))
- A.amount_left = 0
- else
- to_chat(user, span_notice("You reload [7 - src.bullets] cap\s."))
- A.amount_left -= 7 - src.bullets
- src.bullets = 7
- A.update_appearance()
- return 1
+ if(!istype(tool, /obj/item/toy/ammo/gun))
+ return NONE
+ var/obj/item/toy/ammo/gun/ammunition = tool
+ if (bullets >= 7)
+ to_chat(user, span_warning("It's already fully loaded!"))
+ return ITEM_INTERACT_BLOCKING
+ if (ammunition.amount_left <= 0)
+ to_chat(user, span_warning("There are no more caps!"))
+ return ITEM_INTERACT_BLOCKING
+ if (ammunition.amount_left < (7 - bullets))
+ bullets += ammunition.amount_left
+ to_chat(user, span_notice("You reload [ammunition.amount_left] cap\s."))
+ ammunition.amount_left = 0
else
- return ..()
+ to_chat(user, span_notice("You reload [7 - bullets] cap\s."))
+ ammunition.amount_left -= 7 - bullets
+ bullets = 7
+ tool.update_appearance()
+ return ITEM_INTERACT_SUCCESS
/obj/item/toy/gun/ranged_interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(!ISADVANCEDTOOLUSER(user))
to_chat(user, span_warning("You don't have the dexterity to do this!"))
return ITEM_INTERACT_BLOCKING
- src.add_fingerprint(user)
- if (src.bullets < 1)
+ add_fingerprint(user)
+ if (bullets < 1)
user.show_message(span_warning("*click*"), MSG_AUDIBLE)
playsound(src, 'sound/items/weapons/gun/revolver/dry_fire.ogg', 30, TRUE)
return ITEM_INTERACT_SUCCESS
playsound(user, 'sound/items/weapons/gun/revolver/shot.ogg', 100, TRUE)
- src.bullets--
+ bullets--
user.visible_message(span_danger("[user] fires [src] at [interacting_with]!"), \
span_danger("You fire [src] at [interacting_with]!"), \
span_hear("You hear a gunshot!"))
@@ -668,28 +674,26 @@
to_chat(user, span_warning("RNBW_ENGAGE"))
update_appearance(UPDATE_ICON)
+/obj/item/toy/sword/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(!istype(tool, /obj/item/toy/sword))
+ return NONE
+ var/obj/item/toy/sword/attatched_sword = tool
+ if(HAS_TRAIT(tool, TRAIT_NODROP))
+ to_chat(user, span_warning("[tool] is stuck to your hand, you can't attach it to [src]!"))
+ return ITEM_INTERACT_BLOCKING
+ if(HAS_TRAIT(src, TRAIT_NODROP))
+ to_chat(user, span_warning("[src] is stuck to your hand, you can't attach it to [tool]!"))
+ return ITEM_INTERACT_BLOCKING
-// Copied from /obj/item/melee/energy/sword/attackby
-/obj/item/toy/sword/attackby(obj/item/weapon, mob/living/user, list/modifiers, list/attack_modifiers)
- if(istype(weapon, /obj/item/toy/sword))
- var/obj/item/toy/sword/attatched_sword = weapon
- if(HAS_TRAIT(weapon, TRAIT_NODROP))
- to_chat(user, span_warning("[weapon] is stuck to your hand, you can't attach it to [src]!"))
- return
- else if(HAS_TRAIT(src, TRAIT_NODROP))
- to_chat(user, span_warning("[src] is stuck to your hand, you can't attach it to [weapon]!"))
- return
- else
- to_chat(user, span_notice("You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool."))
- var/obj/item/dualsaber/toy/new_saber = new /obj/item/dualsaber/toy(user.loc)
- if(attatched_sword.hacked || hacked)
- new_saber.hacked = TRUE
- new_saber.saber_color = "rainbow"
- qdel(weapon)
- qdel(src)
- user.put_in_hands(new_saber)
- else
- return ..()
+ to_chat(user, span_notice("You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool."))
+ var/obj/item/dualsaber/toy/new_saber = new /obj/item/dualsaber/toy(user.loc)
+ if(attatched_sword.hacked || hacked)
+ new_saber.hacked = TRUE
+ new_saber.saber_color = "rainbow"
+ qdel(tool)
+ qdel(src)
+ user.put_in_hands(new_saber)
+ return ITEM_INTERACT_SUCCESS
/*
* Foam armblade
diff --git a/code/game/objects/items/wind_turbine.dm b/code/game/objects/items/wind_turbine.dm
index 4b89a679582..cdbba2cbba0 100644
--- a/code/game/objects/items/wind_turbine.dm
+++ b/code/game/objects/items/wind_turbine.dm
@@ -243,31 +243,33 @@
update_appearance()
return ..()
-/obj/item/portable_wind_turbine/attackby(obj/item/attacking_item, mob/user, params)
- if(istype(attacking_item, /obj/item/stock_parts/capacitor))
+/obj/item/portable_wind_turbine/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
+ if(istype(tool, /obj/item/stock_parts/capacitor))
if (cap)
balloon_alert(user, "already has a capacitor!")
- return TRUE
- user.transferItemToLoc(attacking_item, src)
- cap = attacking_item
- balloon_alert(user, "inserted the [attacking_item]")
- return TRUE
- if(!is_type_in_typecache(attacking_item, allowed_devices))
- return ..()
+ return ITEM_INTERACT_BLOCKING
+ user.transferItemToLoc(tool, src)
+ cap = tool
+ balloon_alert(user, "inserted the [tool]")
+ return ITEM_INTERACT_SUCCESS
+
+ if(!is_type_in_typecache(tool, allowed_devices))
+ return NONE
+
if(isnull(cap))
balloon_alert(user, "no capacitor inserted!")
- return TRUE
+ return ITEM_INTERACT_BLOCKING
if(charging)
balloon_alert(user, "already charging something!")
- return TRUE
- if(istype(attacking_item, /obj/item/gun/energy))
- var/obj/item/gun/energy/energy_gun = attacking_item
+ return ITEM_INTERACT_BLOCKING
+ if(istype(tool, /obj/item/gun/energy))
+ var/obj/item/gun/energy/energy_gun = tool
if(!energy_gun.can_charge)
balloon_alert(user, "not rechargable!")
- return TRUE
- user.transferItemToLoc(attacking_item, src)
- charging = attacking_item
- return TRUE
+ return ITEM_INTERACT_BLOCKING
+ user.transferItemToLoc(tool, src)
+ charging = tool
+ return ITEM_INTERACT_SUCCESS
/obj/item/portable_wind_turbine/attack_hand(mob/user, list/modifiers)
if(loc == user || (istype(loc, /turf) && !isnull(charging)))