diff --git a/_maps/map_files/tests/test_attack_chain_machinery.dmm b/_maps/map_files/tests/test_attack_chain_machinery.dmm
new file mode 100644
index 000000000000..24a783649a86
--- /dev/null
+++ b/_maps/map_files/tests/test_attack_chain_machinery.dmm
@@ -0,0 +1,617 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"aE" = (
+/obj/machinery/doppler_array,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"aZ" = (
+/obj/machinery/chem_heater,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"cT" = (
+/obj/machinery/biogenerator,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"dW" = (
+/obj/machinery/fishtank,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"fc" = (
+/obj/machinery/door/firedoor,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"fj" = (
+/obj/machinery/chem_dispenser,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"fU" = (
+/obj/machinery/economy/vending/wallmed/directional/north,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"gG" = (
+/turf/simulated/floor/mech_bay_recharge_floor,
+/area/game_test)
+"ht" = (
+/obj/machinery/atmospherics/pipe/simple/hidden/blue{
+ dir = 5
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"hL" = (
+/obj/machinery/bookbinder,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"hU" = (
+/obj/machinery/economy/vending/atmosdrobe,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"ic" = (
+/obj/machinery/door/airlock/external,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"iC" = (
+/obj/machinery/bottler,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"ja" = (
+/obj/structure/table,
+/obj/machinery/cell_charger,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"jW" = (
+/obj/machinery/optable,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"kV" = (
+/obj/machinery/computer/emergency_shuttle,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"lr" = (
+/obj/machinery/computer/aiupload,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"lM" = (
+/obj/machinery/computer/guestpass{
+ pixel_y = 32
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"lO" = (
+/obj/machinery/atmospherics/pipe/simple/hidden/blue{
+ dir = 6
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"mz" = (
+/obj/machinery/computer/med_data/laptop,
+/obj/structure/table,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"nt" = (
+/obj/machinery/atmospherics/pipe/simple/hidden/blue{
+ dir = 10
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"oh" = (
+/obj/machinery/atmospherics/unary/tank/oxygen,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"px" = (
+/obj/machinery/atmospherics/portable/scrubber,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"qc" = (
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"qN" = (
+/obj/machinery/cryopod{
+ dir = 4
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"sj" = (
+/obj/machinery/sleeper{
+ dir = 4
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"so" = (
+/obj/machinery/dna_scannernew,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"tn" = (
+/obj/machinery/computer/security/telescreen/rd{
+ pixel_y = 32
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"to" = (
+/obj/machinery/door/airlock,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"tL" = (
+/obj/machinery/economy/slot_machine,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"ud" = (
+/obj/machinery/abductor/gland_dispenser,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"vi" = (
+/obj/effect/landmark/game_test/top_right_corner,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"vL" = (
+/obj/effect/landmark{
+ icon = 'icons/effects/spawner_icons.dmi';
+ icon_state = "spooky";
+ name = "Observer-Start"
+ },
+/obj/effect/landmark/spawner/late/crew,
+/obj/effect/landmark/game_test/bottom_left_corner,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"ws" = (
+/obj/machinery/computer/library,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"ye" = (
+/obj/machinery/computer/card,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"zA" = (
+/obj/machinery/computer/communications,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Au" = (
+/turf/simulated/wall/r_wall,
+/area/game_test)
+"AM" = (
+/obj/machinery/conveyor_switch,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Bi" = (
+/obj/machinery/atmospherics/pipe/simple/hidden/blue{
+ dir = 9
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Bn" = (
+/obj/machinery/atmospherics/pipe/simple/hidden/blue{
+ dir = 4
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Bo" = (
+/obj/machinery/r_n_d/circuit_imprinter,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"CH" = (
+/obj/machinery/clonepod,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"EK" = (
+/obj/machinery/mech_bay_recharge_port,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Fl" = (
+/obj/machinery/compost_bin,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Ge" = (
+/obj/machinery/mecha_part_fabricator,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"KW" = (
+/obj/machinery/nuclearbomb/undeployed,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"KY" = (
+/obj/machinery/computer/mech_bay_power_console,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Lb" = (
+/obj/machinery/atmospherics/portable/pump,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"LT" = (
+/obj/machinery/computer/cloning,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Mh" = (
+/obj/machinery/economy/atm/directional/north,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Mr" = (
+/obj/machinery/floodlight,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Ng" = (
+/obj/machinery/abductor/console,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"NE" = (
+/obj/machinery/alarm/directional/north,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"OG" = (
+/obj/machinery/cryopod/robot,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Qx" = (
+/obj/machinery/computer/arcade,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"RD" = (
+/obj/machinery/r_n_d/protolathe,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"RO" = (
+/obj/machinery/computer/operating,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"RP" = (
+/obj/machinery/autolathe,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"SZ" = (
+/obj/machinery/button/windowtint,
+/turf/simulated/wall/r_wall,
+/area/game_test)
+"TH" = (
+/obj/machinery/computer/scan_consolenew,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Ua" = (
+/obj/machinery/conveyor{
+ dir = 4
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Uk" = (
+/obj/machinery/clonescanner,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"VL" = (
+/obj/machinery/chem_master,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"WF" = (
+/obj/machinery/camera,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Xs" = (
+/obj/machinery/bodyscanner{
+ dir = 4
+ },
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"YO" = (
+/obj/machinery/atmospherics/pipe/simple/hidden/blue,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+"Zk" = (
+/obj/machinery/door/firedoor/closed,
+/turf/simulated/floor/plasteel,
+/area/game_test)
+
+(1,1,1) = {"
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+"}
+(2,1,1) = {"
+Au
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+Au
+"}
+(3,1,1) = {"
+Au
+qc
+qc
+qc
+oh
+qc
+SZ
+qc
+hL
+qc
+AM
+qc
+Qx
+qc
+dW
+vL
+qc
+Au
+"}
+(4,1,1) = {"
+Au
+qc
+qc
+qc
+iC
+qc
+Au
+NE
+ws
+qc
+Ua
+qc
+Fl
+qc
+Mr
+qc
+qc
+Au
+"}
+(5,1,1) = {"
+Au
+qc
+qc
+mz
+qc
+qc
+Au
+tn
+fj
+qc
+Ua
+qc
+aE
+qc
+tL
+qc
+qc
+Au
+"}
+(6,1,1) = {"
+Au
+qc
+qc
+ja
+qc
+qc
+Au
+Mh
+aZ
+qc
+lr
+qc
+hU
+qc
+qN
+qc
+qc
+Au
+"}
+(7,1,1) = {"
+Au
+qc
+qc
+qc
+qc
+qc
+Au
+fU
+CH
+qc
+to
+qc
+Zk
+qc
+Xs
+qc
+qc
+Au
+"}
+(8,1,1) = {"
+Au
+qc
+qc
+qc
+qc
+qc
+Au
+lM
+VL
+qc
+ic
+qc
+fc
+qc
+qc
+qc
+qc
+Au
+"}
+(9,1,1) = {"
+Au
+qc
+qc
+qc
+qc
+qc
+Au
+qc
+RO
+qc
+RD
+qc
+OG
+qc
+sj
+qc
+qc
+Au
+"}
+(10,1,1) = {"
+Au
+qc
+lO
+YO
+ht
+qc
+Au
+WF
+jW
+qc
+px
+qc
+Ge
+qc
+Ng
+qc
+qc
+Au
+"}
+(11,1,1) = {"
+Au
+qc
+Bn
+qc
+Bn
+qc
+cT
+qc
+Uk
+qc
+Lb
+qc
+KW
+qc
+ud
+qc
+qc
+Au
+"}
+(12,1,1) = {"
+Au
+qc
+nt
+YO
+Bi
+qc
+qc
+qc
+LT
+qc
+so
+qc
+EK
+qc
+ye
+qc
+qc
+Au
+"}
+(13,1,1) = {"
+Au
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+RP
+qc
+TH
+qc
+gG
+qc
+zA
+qc
+qc
+Au
+"}
+(14,1,1) = {"
+Au
+qc
+vi
+qc
+qc
+qc
+qc
+qc
+Bo
+qc
+qc
+qc
+KY
+qc
+kV
+qc
+qc
+Au
+"}
+(15,1,1) = {"
+Au
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+qc
+Au
+"}
+(16,1,1) = {"
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+Au
+"}
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index e6f5604890cb..2031313ff54a 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -177,6 +177,10 @@
/proc/get_mobs_in_view(R, atom/source, include_clientless = FALSE)
// Returns a list of mobs in range of R from source. Used in radio and say code.
+#ifdef GAME_TESTS
+ // kind of feels cleaner clobbering here than changing the loop?
+ include_clientless = TRUE
+#endif
var/turf/T = get_turf(source)
var/list/hear = list()
diff --git a/code/game/area/misc_areas.dm b/code/game/area/misc_areas.dm
index e9bd5f40a6a4..1eda79444595 100644
--- a/code/game/area/misc_areas.dm
+++ b/code/game/area/misc_areas.dm
@@ -50,6 +50,7 @@
/area/game_test
name = "Game Test Area"
+ requires_power = FALSE
//SYNDICATES
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index c85ff6a05c3b..417a8c303ff6 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -190,47 +190,47 @@
QDEL_LIST_CONTENTS(L.grabbed_by)
return TRUE
-/obj/machinery/dna_scannernew/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/reagent_containers/glass))
+/obj/machinery/dna_scannernew/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/reagent_containers/glass))
if(beaker)
to_chat(user, "A beaker is already loaded into the machine.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- to_chat(user, "\The [I] is stuck to you!")
- return
+ to_chat(user, "\The [used] is stuck to you!")
+ return ITEM_INTERACT_COMPLETE
- beaker = I
+ beaker = used
SStgui.update_uis(src)
- I.forceMove(src)
- user.visible_message("[user] adds \a [I] to \the [src]!", "You add \a [I] to \the [src]!")
- return
+ used.forceMove(src)
+ user.visible_message("[user] adds \a [used] to \the [src]!", "You add \a [used] to \the [src]!")
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/grab))
- var/obj/item/grab/G = I
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/G = used
if(!ismob(G.affecting))
- return
+ return ITEM_INTERACT_COMPLETE
if(occupant)
to_chat(user, "The scanner is already occupied!")
- return
+ return ITEM_INTERACT_COMPLETE
if(G.affecting.abiotic())
to_chat(user, "Subject may not hold anything in their hands.")
- return
+ return ITEM_INTERACT_COMPLETE
if(G.affecting.has_buckled_mobs()) //mob attached to us
to_chat(user, "[G] will not fit into [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.")
- return
+ return ITEM_INTERACT_COMPLETE
if(panel_open)
to_chat(usr, "Close the maintenance panel first.")
- return
+ return ITEM_INTERACT_COMPLETE
put_in(G.affecting)
add_fingerprint(user)
qdel(G)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
@@ -327,17 +327,18 @@
idle_power_consumption = 10
active_power_consumption = 400
-/obj/machinery/computer/scan_consolenew/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/disk/data)) //INSERT SOME diskS
+/obj/machinery/computer/scan_consolenew/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/disk/data)) //INSERT SOME diskS
if(!disk)
user.drop_item()
- I.forceMove(src)
- disk = I
- to_chat(user, "You insert [I].")
+ used.forceMove(src)
+ disk = used
+ to_chat(user, "You insert [used].")
SStgui.update_uis(src)
- return
- else
- return ..()
+
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/computer/scan_consolenew/Initialize(mapload)
. = ..()
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
index f1539a992917..aaebe3544043 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm
@@ -218,13 +218,15 @@
vest = V
return TRUE
-/obj/machinery/abductor/console/attackby__legacy__attackchain(obj/O, mob/user, params)
- if(istype(O, /obj/item/abductor/gizmo) && AddGizmo(O))
+/obj/machinery/abductor/console/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/abductor/gizmo) && AddGizmo(used))
to_chat(user, "You link the tool to the console.")
- else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest) && AddVest(O))
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/clothing/suit/armor/abductor/vest) && AddVest(used))
to_chat(user, "You link the vest to the console.")
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/abductor/console/proc/Dispense(item,cost=1)
if(experiment && experiment.credits >= cost)
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
index 9d70325835a9..ce8c1ef9a0c2 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
@@ -82,16 +82,17 @@
return
ui_interact(user)
-/obj/machinery/abductor/gland_dispenser/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/organ/internal/heart/gland))
+/obj/machinery/abductor/gland_dispenser/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/organ/internal/heart/gland))
if(!user.drop_item())
- return
- W.forceMove(src)
+ return ITEM_INTERACT_COMPLETE
+ used.forceMove(src)
for(var/i in 1 to length(gland_colors))
- if(gland_types[i] == W.type)
+ if(gland_types[i] == used.type)
amounts[i]++
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/abductor/gland_dispenser/proc/Dispense(count)
if(amounts[count]>0)
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index 2084fdab665e..1d195d25f359 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -177,19 +177,19 @@
H.clear_restraints()
return
-/obj/machinery/abductor/experiment/attackby__legacy__attackchain(obj/item/G, mob/user)
- if(istype(G, /obj/item/grab))
- var/obj/item/grab/grabbed = G
+/obj/machinery/abductor/experiment/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/grabbed = used
if(!ishuman(grabbed.affecting))
- return
+ return ITEM_INTERACT_COMPLETE
if(isabductor(grabbed.affecting))
- return
+ return ITEM_INTERACT_COMPLETE
if(occupant)
to_chat(user, "[src] is already occupied!")
- return
+ return ITEM_INTERACT_COMPLETE
if(grabbed.affecting.has_buckled_mobs()) //mob attached to us
to_chat(user, "[grabbed.affecting] will not fit into [src] because [grabbed.affecting.p_they()] [grabbed.affecting.p_have()] a slime latched onto [grabbed.affecting.p_their()] head.")
- return
+ return ITEM_INTERACT_COMPLETE
visible_message("[user] puts [grabbed.affecting] into [src].")
var/mob/living/carbon/human/H = grabbed.affecting
H.forceMove(src)
@@ -197,8 +197,9 @@
flash = "Machine ready."
update_icon(UPDATE_ICON_STATE)
add_fingerprint(user)
- qdel(G)
- return
+ qdel(used)
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/abductor/experiment/ex_act(severity)
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 9baefc703068..df04fae1ac8e 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -168,33 +168,34 @@ GLOBAL_VAR(bomb_set)
if(NUKE_CORE_FULLY_EXPOSED)
. += core ? "nukecore3" : "nukecore4"
-/obj/machinery/nuclearbomb/attackby__legacy__attackchain(obj/item/O as obj, mob/user as mob, params)
- if(istype(O, /obj/item/disk/nuclear))
+/obj/machinery/nuclearbomb/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/disk/nuclear))
if(extended)
if(auth)
to_chat(user, "There's already a disk in the slot!")
- return
- if((istype(O, /obj/item/disk/nuclear/training) && !training) || (training && !istype(O, /obj/item/disk/nuclear/training)))
- to_chat(user, "[O] doesn't fit into [src]!")
- return
+ return ITEM_INTERACT_COMPLETE
+ if((istype(used, /obj/item/disk/nuclear/training) && !training) || (training && !istype(used, /obj/item/disk/nuclear/training)))
+ to_chat(user, "[used] doesn't fit into [src]!")
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- to_chat(user, "[O] is stuck to your hand!")
- return
- O.forceMove(src)
- auth = O
+ to_chat(user, "[used] is stuck to your hand!")
+ return ITEM_INTERACT_COMPLETE
+ used.forceMove(src)
+ auth = used
add_fingerprint(user)
- return attack_hand(user)
+ attack_hand(user)
+ return ITEM_INTERACT_COMPLETE
else
to_chat(user, "You need to deploy [src] first.")
- return
- if(istype(O, /obj/item/stack/sheet/mineral/titanium) && removal_stage == NUKE_CORE_FULLY_EXPOSED)
- var/obj/item/stack/S = O
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/stack/sheet/mineral/titanium) && removal_stage == NUKE_CORE_FULLY_EXPOSED)
+ var/obj/item/stack/S = used
if(S.get_amount() < sheets_to_fix)
to_chat(user, "You need at least [sheets_to_fix] sheets of titanium to repair [src]'s inner core plate!")
- return
+ return ITEM_INTERACT_COMPLETE
if(do_after(user, 2 SECONDS, target = src))
if(!loc || !S || S.get_amount() < sheets_to_fix)
- return
+ return ITEM_INTERACT_COMPLETE
S.use(sheets_to_fix)
user.visible_message("[user] repairs [src]'s inner core plate.", \
"You repair [src]'s inner core plate. The radiation is contained.")
@@ -202,43 +203,43 @@ GLOBAL_VAR(bomb_set)
if(core)
STOP_PROCESSING(SSobj, core)
update_icon(UPDATE_OVERLAYS)
- return
- if(istype(O, /obj/item/stack/sheet/metal) && removal_stage == NUKE_CORE_PANEL_EXPOSED)
- var/obj/item/stack/S = O
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/stack/sheet/metal) && removal_stage == NUKE_CORE_PANEL_EXPOSED)
+ var/obj/item/stack/S = used
if(S.get_amount() < sheets_to_fix)
to_chat(user, "You need at least [sheets_to_fix] sheets of metal to repair [src]'s outer core plate!")
- return
- if(do_after(user, 2 SECONDS, target = src))
+ else if(do_after(user, 2 SECONDS, target = src))
if(!loc || !S || S.get_amount() < sheets_to_fix)
- return
+ return ITEM_INTERACT_COMPLETE
S.use(sheets_to_fix)
user.visible_message("[user] repairs [src]'s outer core plate.", \
"You repair [src]'s outer core plate.")
removal_stage = NUKE_CORE_EVERYTHING_FINE
update_icon(UPDATE_OVERLAYS)
- return
- if(istype(O, /obj/item/nuke_core/plutonium) && removal_stage == NUKE_CORE_FULLY_EXPOSED)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/nuke_core/plutonium) && removal_stage == NUKE_CORE_FULLY_EXPOSED)
if(do_after(user, 2 SECONDS, target = src))
- if(!user.drop_item_to_ground(O))
- to_chat(user, "The [O] is stuck to your hand!")
+ if(!user.drop_item_to_ground(used))
+ to_chat(user, "The [used] is stuck to your hand!")
return
- user.visible_message("[user] puts [O] back in [src].", "You put [O] back in [src].")
- O.forceMove(src)
- core = O
+ user.visible_message("[user] puts [used] back in [src].", "You put [used] back in [src].")
+ used.forceMove(src)
+ core = used
update_icon(UPDATE_OVERLAYS)
- return
- if(istype(O, /obj/item/disk/plantgene))
+ return ITEM_INTERACT_COMPLETE
+
+ if(istype(used, /obj/item/disk/plantgene))
to_chat(user, "You try to plant the disk, but despite rooting around, it won't fit! After you branch out to read the instructions, you find out where the problem stems from. You've been bamboo-zled, this isn't a nuclear disk at all!")
- return
+ return ITEM_INTERACT_COMPLETE
- else if(istype(O, /obj/item/disk))
- if(O.icon_state == "datadisk4") //A similar green disk icon
+ else if(istype(used, /obj/item/disk))
+ if(used.icon_state == "datadisk4") //A similar green disk icon
to_chat(user, "You try to slot in the disk, but it won't fit! This isn't the NAD! If only you'd read the label...")
- return
+ return ITEM_INTERACT_COMPLETE
else
to_chat(user, "You try to slot in the disk, but it won't fit. This isn't the NAD! It's not even the right colour...")
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
@@ -386,20 +387,24 @@ GLOBAL_VAR(bomb_set)
/obj/machinery/nuclearbomb/attack_hand(mob/user as mob)
if(!panel_open)
- return ui_interact(user)
+ ui_interact(user)
+ return FINISH_ATTACK
if(!Adjacent(user))
return
if(removal_stage != NUKE_CORE_FULLY_EXPOSED || !core)
- return wires.Interact(user)
+ wires.Interact(user)
+ return FINISH_ATTACK
if(timing) //removing the core is less risk then cutting wires, and doesnt take long, so we should not let crew do it while the nuke is armed. You can however get to it, without the special screwdriver, if you put the NAD in.
to_chat(user, "[core] won't budge, metal clamps keep it in!")
- return
+ return FINISH_ATTACK
user.visible_message("[user] starts to pull [core] out of [src]!", "You start to pull [core] out of [src]!")
if(do_after(user, 5 SECONDS, target = src))
user.visible_message("[user] pulls [core] out of [src]!", "You pull [core] out of [src]! Might want to put it somewhere safe.")
core.forceMove(loc)
core = null
+
update_icon(UPDATE_OVERLAYS)
+ return FINISH_ATTACK
/obj/machinery/nuclearbomb/ui_state(mob/user)
return GLOB.physical_state
diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm
index b2dfdb8679cc..0bac558e2242 100644
--- a/code/game/machinery/PDApainter.dm
+++ b/code/game/machinery/PDApainter.dm
@@ -71,14 +71,15 @@
storedpda = null
update_icon()
-/obj/machinery/pdapainter/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(default_unfasten_wrench(user, I))
+/obj/machinery/pdapainter/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_unfasten_wrench(user, used))
power_change()
- return
- if(istype(I, /obj/item/pda))
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/pda))
insertpda(user)
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/pdapainter/welder_act(mob/user, obj/item/I)
. = TRUE
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index d10068371063..acd184eecd2e 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -300,49 +300,49 @@
return FALSE
add_fingerprint(usr)
-/obj/machinery/sleeper/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/reagent_containers/glass) && user.a_intent != INTENT_HARM)
+/obj/machinery/sleeper/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/reagent_containers/glass) && user.a_intent != INTENT_HARM)
if(!beaker)
if(!user.drop_item())
- to_chat(user, "[I] is stuck to you!")
- return
+ to_chat(user, "[used] is stuck to you!")
+ return ITEM_INTERACT_COMPLETE
- beaker = I
- I.forceMove(src)
- user.visible_message("[user] adds \a [I] to [src]!", "You add \a [I] to [src]!")
+ beaker = used
+ used.forceMove(src)
+ user.visible_message("[user] adds \a [used] to [src]!", "You add \a [used] to [src]!")
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
else
to_chat(user, "The sleeper has a beaker already.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/grab))
- var/obj/item/grab/G = I
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/G = used
if(panel_open)
to_chat(user, "Close the maintenance panel first.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!ismob(G.affecting))
- return
+ return ITEM_INTERACT_COMPLETE
if(occupant)
to_chat(user, "The sleeper is already occupied!")
- return
+ return ITEM_INTERACT_COMPLETE
if(G.affecting.has_buckled_mobs()) //mob attached to us
to_chat(user, "[G.affecting] will not fit into [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.")
- return
+ return ITEM_INTERACT_COMPLETE
visible_message("[user] starts putting [G.affecting.name] into the sleeper.")
if(do_after(user, 20, target = G.affecting))
if(occupant)
to_chat(user, "The sleeper is already occupied!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!G || !G.affecting)
- return
+ return ITEM_INTERACT_COMPLETE
var/mob/M = G.affecting
M.forceMove(src)
@@ -352,7 +352,7 @@
add_fingerprint(user)
qdel(G)
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index ab53feea9596..a09c0b900b57 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -64,28 +64,28 @@
else
icon_state = "bodyscanner-open"
-/obj/machinery/bodyscanner/attackby__legacy__attackchain(obj/item/I, mob/user)
- if(istype(I, /obj/item/grab))
- var/obj/item/grab/TYPECAST_YOUR_SHIT = I
+/obj/machinery/bodyscanner/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/TYPECAST_YOUR_SHIT = used
if(panel_open)
to_chat(user, "Close the maintenance panel first.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!ishuman(TYPECAST_YOUR_SHIT.affecting))
- return
+ return ITEM_INTERACT_COMPLETE
if(occupant)
to_chat(user, "The scanner is already occupied!")
- return
+ return ITEM_INTERACT_COMPLETE
if(TYPECAST_YOUR_SHIT.affecting.has_buckled_mobs()) //mob attached to us
to_chat(user, "[TYPECAST_YOUR_SHIT.affecting] will not fit into [src] because [TYPECAST_YOUR_SHIT.affecting.p_they()] [TYPECAST_YOUR_SHIT.affecting.p_have()] a fucking slime latched onto [TYPECAST_YOUR_SHIT.affecting.p_their()] head.")
- return
+ return ITEM_INTERACT_COMPLETE
var/mob/living/carbon/human/M = TYPECAST_YOUR_SHIT.affecting
if(M.abiotic())
to_chat(user, "Subject may not hold anything in their hands.")
- return
+ return ITEM_INTERACT_COMPLETE
M.forceMove(src)
occupant = M
@@ -94,7 +94,7 @@
add_fingerprint(user)
qdel(TYPECAST_YOUR_SHIT)
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/game/machinery/airlock_control/airlock_button.dm b/code/game/machinery/airlock_control/airlock_button.dm
index a4f9ed2c77e7..649cce770091 100644
--- a/code/game/machinery/airlock_control/airlock_button.dm
+++ b/code/game/machinery/airlock_control/airlock_button.dm
@@ -32,11 +32,12 @@ GLOBAL_LIST_EMPTY(all_airlock_access_buttons)
else
icon_state = "access_button_off"
-/obj/machinery/access_button/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- //Swiping ID on the access button
- if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
+/obj/machinery/access_button/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ // Swiping ID on the access button
+ if(istype(used, /obj/item/card/id) || istype(used, /obj/item/pda))
attack_hand(user)
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/access_button/attack_ghost(mob/user)
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index b002ff4405cf..091cb5a27b23 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -37,6 +37,7 @@
var/list/categories = list("Tools", "Electronics", "Construction", "Communication", "Security", "Machinery", "Medical", "Miscellaneous", "Dinnerware", "Imported")
var/board_type = /obj/item/circuitboard/autolathe
+ var/disk_design_load_delay = 1.5 SECONDS
/obj/machinery/autolathe/Initialize(mapload)
. = ..()
@@ -263,18 +264,18 @@
data["queue"] = null
return data
-/obj/machinery/autolathe/attackby__legacy__attackchain(obj/item/O, mob/user, params)
+/obj/machinery/autolathe/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(busy)
to_chat(user, "The autolathe is busy. Please wait for completion of previous operation.")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
if(stat)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
// Disks in general
- if(istype(O, /obj/item/disk))
- if(istype(O, /obj/item/disk/design_disk))
- var/obj/item/disk/design_disk/D = O
+ if(istype(used, /obj/item/disk))
+ if(istype(used, /obj/item/disk/design_disk))
+ var/obj/item/disk/design_disk/D = used
if(D.blueprint)
var/datum/design/design = D.blueprint // READ ONLY!!
@@ -287,13 +288,13 @@
return TRUE
user.visible_message(
- "[user] begins to load \the [O] in \the [src]...",
- "You begin to load a design from \the [O]...",
+ "[user] begins to load \the [used] in \the [src]...",
+ "You begin to load a design from \the [used]...",
"You hear the chatter of a floppy drive."
)
playsound(get_turf(src), 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1)
busy = TRUE
- if(do_after(user, 14.4, target = src))
+ if(do_after(user, disk_design_load_delay, target = src))
imported[design.id] = TRUE
files.AddDesign2Known(design)
recipiecache = list()
@@ -301,12 +302,12 @@
busy = FALSE
else
to_chat(user, "That disk does not have a design on it!")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
else
// So that people who are bad at computers don't shred their disks
to_chat(user, "This is not the correct type of disk for the autolathe!")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index bc793fadcc35..b0c397130804 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -141,37 +141,40 @@
toggle_cam(null, 0)
..()
-/obj/machinery/camera/attackby__legacy__attackchain(obj/item/I, mob/living/user, params)
- var/msg = "You attach [I] into the assembly inner circuits."
+/obj/machinery/camera/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ var/msg = "You attach [used] into the assembly inner circuits."
var/msg2 = "The camera already has that upgrade!"
- if(istype(I, /obj/item/stack/sheet/mineral/plasma) && panel_open)
- if(!user.canUnEquip(I, FALSE))
- to_chat(user, "[I] is stuck to your hand!")
- return
+ if(istype(used, /obj/item/stack/sheet/mineral/plasma) && panel_open)
+ if(!user.canUnEquip(used, FALSE))
+ to_chat(user, "[used] is stuck to your hand!")
+ return ITEM_INTERACT_COMPLETE
if(!isEmpProof())
- var/obj/item/stack/sheet/mineral/plasma/P = I
+ var/obj/item/stack/sheet/mineral/plasma/P = used
upgradeEmpProof()
to_chat(user, "[msg]")
P.use(1)
+ return ITEM_INTERACT_COMPLETE
else
to_chat(user, "[msg2]")
- else if(istype(I, /obj/item/assembly/prox_sensor) && panel_open)
- if(!user.canUnEquip(I, FALSE))
- to_chat(user, "[I] is stuck to your hand!")
- return
+ else if(istype(used, /obj/item/assembly/prox_sensor) && panel_open)
+ if(!user.canUnEquip(used, FALSE))
+ to_chat(user, "[used] is stuck to your hand!")
+ return ITEM_INTERACT_COMPLETE
if(!isMotion())
upgradeMotion()
to_chat(user, "[msg]")
- qdel(I)
+ qdel(used)
else
to_chat(user, "[msg2]")
+ return ITEM_INTERACT_COMPLETE
+
// OTHER
- else if((istype(I, /obj/item/paper) || istype(I, /obj/item/pda)) && isliving(user))
+ else if((istype(used, /obj/item/paper) || istype(used, /obj/item/pda)) && isliving(user))
if(!can_use())
to_chat(user, "You can't show something to a disabled camera!")
- return
+ return ITEM_INTERACT_COMPLETE
var/mob/living/U = user
var/obj/item/paper/X = null
@@ -179,12 +182,12 @@
var/itemname = ""
var/info = ""
- if(istype(I, /obj/item/paper))
- X = I
+ if(istype(used, /obj/item/paper))
+ X = used
itemname = X.name
info = X.info
else
- PDA = I
+ PDA = used
var/datum/data/pda/app/notekeeper/N = PDA.find_program(/datum/data/pda/app/notekeeper)
if(N)
itemname = PDA.name
@@ -195,7 +198,7 @@
if(is_ai(O))
var/mob/living/silicon/ai/AI = O
if(AI.control_disabled || (AI.stat == DEAD))
- return
+ return ITEM_INTERACT_COMPLETE
if(U.name == "Unknown")
to_chat(AI, "[U] holds \a [itemname] up to one of your cameras ...")
else
@@ -204,13 +207,11 @@
else if(O.client && O.client.eye == src)
to_chat(O, "[U] holds \a [itemname] up to one of the cameras ...")
O << browse("
[itemname][info]", "window=[itemname]")
-
- else if(istype(I, /obj/item/laser_pointer))
- var/obj/item/laser_pointer/L = I
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/laser_pointer))
+ var/obj/item/laser_pointer/L = used
L.laser_act(src, user)
- else
- return ..()
-
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/camera/screwdriver_act(mob/user, obj/item/I)
. = TRUE
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index 3b1f8c908438..b60930e4be31 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -60,34 +60,35 @@
if(charging)
. += "Current charge: [round(charging.percent(), 1)]%"
-/obj/machinery/cell_charger/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/stock_parts/cell) && !panel_open)
+/obj/machinery/cell_charger/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/stock_parts/cell) && !panel_open)
if(stat & BROKEN)
to_chat(user, "[src] is broken!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!anchored)
to_chat(user, "[src] isn't attached to the ground!")
- return
+ return ITEM_INTERACT_COMPLETE
if(charging)
to_chat(user, "There is already a cell in the charger!")
- return
+ return ITEM_INTERACT_COMPLETE
else
var/area/a = loc.loc // Gets our locations location, like a dream within a dream
if(!isarea(a))
- return
+ return ITEM_INTERACT_COMPLETE
if(!a.powernet.has_power(PW_CHANNEL_EQUIPMENT)) // There's no APC in this area, don't try to cheat power!
to_chat(user, "[src] blinks red as you try to insert the cell!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- return
+ return ITEM_INTERACT_COMPLETE
- I.forceMove(src)
- charging = I
+ used.forceMove(src)
+ charging = used
user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.")
check_level()
update_icon(UPDATE_OVERLAYS)
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/cell_charger/crowbar_act(mob/user, obj/item/I)
if(panel_open && !charging && default_deconstruction_crowbar(user, I))
diff --git a/code/game/machinery/clonepod.dm b/code/game/machinery/clonepod.dm
index 396f107fe9b1..5b355fe1d59c 100644
--- a/code/game/machinery/clonepod.dm
+++ b/code/game/machinery/clonepod.dm
@@ -560,26 +560,25 @@
return RP
return FALSE
-//Attackby and x_acts
-/obj/machinery/clonepod/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(I.is_open_container())
- return
+/obj/machinery/clonepod/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(used.is_open_container())
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
+ if(istype(used, /obj/item/card/id) || istype(used, /obj/item/pda))
if(!allowed(user))
to_chat(user, "Access denied.")
- return
+ return ITEM_INTERACT_COMPLETE
switch(tgui_alert(user, "Perform an emergency ejection of [src]?", "Cloning pod", list("Yes", "No")))
if("Yes")
eject_clone(TRUE) // GET OUT
to_chat(user, "You force [src] to eject its clone!")
log_admin("[key_name(user)] has activated a cloning pod's emergency eject at [COORD(src)] (clone: [key_name(clone)])")
- return
+ return ITEM_INTERACT_COMPLETE
- if(is_organ(I) || is_type_in_list(I, ALLOWED_ROBOT_PARTS)) //fun fact, robot parts aren't organs!
- insert_organ(I, user)
- return
+ if(is_organ(used) || is_type_in_list(used, ALLOWED_ROBOT_PARTS)) //fun fact, robot parts aren't organs!
+ insert_organ(used, user)
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm
index 5794a99269b6..a729cc402d45 100644
--- a/code/game/machinery/computer/HolodeckControl.dm
+++ b/code/game/machinery/computer/HolodeckControl.dm
@@ -35,6 +35,7 @@
/obj/machinery/computer/holodeck_control/Initialize(mapload)
. = ..()
linkedholodeck = locate(/area/holodeck/alphadeck)
+ RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by))
/obj/machinery/computer/holodeck_control/Destroy()
emergency_shutdown()
@@ -43,9 +44,6 @@
/obj/machinery/computer/holodeck_control/attack_ai(mob/user)
return attack_hand(user)
-/obj/machinery/computer/holodeck_control/attackby__legacy__attackchain(obj/item/D, mob/user)
- return
-
/obj/machinery/computer/holodeck_control/attack_ghost(mob/user)
ui_interact(user)
return ..()
@@ -438,8 +436,9 @@
to_chat(user, "The station AI is not to interact with these devices.")
return
-/obj/machinery/readybutton/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params)
+/obj/machinery/readybutton/item_interaction(mob/living/user, obj/item/used, list/modifiers)
to_chat(user, "The device is a solid button, there's nothing you can do with it!")
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/readybutton/attack_hand(mob/user)
if(user.stat || stat & (BROKEN))
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index dd3c3014f01e..a902fd306dfd 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -152,7 +152,8 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
else
to_chat(user, "There is nothing to remove from the console.")
-/obj/machinery/computer/card/attackby__legacy__attackchain(obj/item/card/id/id_card, mob/user, params)
+/obj/machinery/computer/card/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ var/obj/item/card/id/id_card = used
if(!istype(id_card))
return ..()
if(istype(id_card, /obj/item/card/id/nct_data_chip))
@@ -172,6 +173,8 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
SStgui.update_uis(src)
attack_hand(user)
+ return ITEM_INTERACT_COMPLETE
+
//Check if you can't touch a job in any way whatsoever
/obj/machinery/computer/card/proc/job_blacklisted_full(datum/job/job)
return (job.type in blacklisted_full)
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index c858e7668e52..6e4988b97f0a 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -47,42 +47,41 @@
P.console = null
return ..()
-/obj/machinery/computer/cloning/attackby__legacy__attackchain(obj/item/I, mob/user, params)
-
- if(!ismultitool(I))
+/obj/machinery/computer/cloning/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(!ismultitool(used))
return ..()
- var/obj/item/multitool/M = I
+ var/obj/item/multitool/M = used
if(!M.buffer)
to_chat(user, "[M]'[M.p_s()] buffer is empty!")
- return
+ return ITEM_INTERACT_COMPLETE
if(istype(M.buffer, /obj/machinery/clonepod))
var/obj/machinery/clonepod/buffer_pod = M.buffer
if(buffer_pod.console == src)
to_chat(user, "[M.buffer] is already linked!")
- return
+ return ITEM_INTERACT_COMPLETE
pods += M.buffer
buffer_pod.console = src
to_chat(user, "[M.buffer] was successfully added to the cloning pod array.")
if(!selected_pod)
selected_pod = buffer_pod
- return
+ return ITEM_INTERACT_COMPLETE
if(istype(M.buffer, /obj/machinery/clonescanner))
var/obj/machinery/clonescanner/buffer_scanner = M.buffer
if(scanner)
to_chat(user, "There's already a linked scanner!")
- return
+ return ITEM_INTERACT_COMPLETE
scanner = buffer_scanner
buffer_scanner.console = src
to_chat(user, "[M.buffer] was successfully linked.")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "[M.buffer] cannot be linked to [src].")
- return
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/computer/cloning/attack_ai(mob/user)
return attack_hand(user)
diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm
index b21fa7102b0b..9da3b2c4e3ad 100644
--- a/code/game/machinery/computer/law.dm
+++ b/code/game/machinery/computer/law.dm
@@ -28,16 +28,19 @@
circuit = /obj/item/circuitboard/aiupload_broken
return TRUE
-/obj/machinery/computer/aiupload/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(!istype(O, /obj/item/ai_module))
+/obj/machinery/computer/aiupload/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ var/obj/item/ai_module/module = used
+ if(!istype(module))
return ..()
if(!check_valid_selection(user))
- return
+ return ITEM_INTERACT_COMPLETE
if(!emagged) //non-emag law change
- var/obj/item/ai_module/M = O
- return M.install(src)
+ module.install(src)
+ return ITEM_INTERACT_COMPLETE
+
apply_emag_laws(user)
- return
+
+ return ITEM_INTERACT_COMPLETE
/// checks to ensure there is a selected AI, and that it is on the same Z level
/obj/machinery/computer/aiupload/proc/check_valid_selection(mob/user)
@@ -127,19 +130,20 @@
circuit = /obj/item/circuitboard/borgupload
var/mob/living/silicon/robot/current = null
-/obj/machinery/computer/borgupload/attackby__legacy__attackchain(obj/item/ai_module/module, mob/user, params)
- if(istype(module, /obj/item/ai_module))
+/obj/machinery/computer/borgupload/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ var/obj/item/ai_module/module = used
+ if(istype(module))
if(!current)//no borg selected
to_chat(user, "No borg selected. Please chose a target before proceeding with upload.")
- return
+ return ITEM_INTERACT_COMPLETE
var/turf/T = get_turf(current)
if(!atoms_share_level(T, src))
to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!")
- return
+ return ITEM_INTERACT_COMPLETE
module.install(src)
- return
- return ..()
+ return ITEM_INTERACT_COMPLETE
+ return ..()
/obj/machinery/computer/borgupload/attack_hand(mob/user)
if(stat & NOPOWER)
diff --git a/code/game/machinery/computer/medical_records.dm b/code/game/machinery/computer/medical_records.dm
index 377765d49950..811c5c847109 100644
--- a/code/game/machinery/computer/medical_records.dm
+++ b/code/game/machinery/computer/medical_records.dm
@@ -63,9 +63,10 @@
active2 = null
return ..()
-/obj/machinery/computer/med_data/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(ui_login_attackby(O, user))
- return
+/obj/machinery/computer/med_data/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(ui_login_attackby(used, user))
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/computer/med_data/attack_hand(mob/user)
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 5df576b11705..4778ba8a8233 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -21,16 +21,17 @@
GLOB.prisoncomputer_list -= src
return ..()
-/obj/machinery/computer/prisoner/attackby__legacy__attackchain(obj/item/O, mob/user, params)
+/obj/machinery/computer/prisoner/item_interaction(mob/living/user, obj/item/used, list/modifiers)
var/datum/ui_login/state = ui_login_get()
if(state.logged_in)
- var/obj/item/card/id/prisoner/I = O
+ var/obj/item/card/id/prisoner/I = used
if(istype(I) && user.drop_item())
I.forceMove(src)
inserted_id_uid = I.UID()
- return
- if(ui_login_attackby(O, user))
- return
+ return ITEM_INTERACT_COMPLETE
+ if(ui_login_attackby(used, user))
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/computer/prisoner/attack_ai(mob/user)
diff --git a/code/game/machinery/computer/security_records.dm b/code/game/machinery/computer/security_records.dm
index bbcb1ad3a71c..8bebd9a7d527 100644
--- a/code/game/machinery/computer/security_records.dm
+++ b/code/game/machinery/computer/security_records.dm
@@ -57,9 +57,10 @@
record_security = null
return ..()
-/obj/machinery/computer/secure_data/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(ui_login_attackby(O, user))
- return
+/obj/machinery/computer/secure_data/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(ui_login_attackby(used, user))
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/computer/secure_data/attack_hand(mob/user)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index fdcfc2518104..765af9c34c68 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -450,64 +450,64 @@
name = initial(name)
-/obj/machinery/cryopod/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/grab))
- var/obj/item/grab/G = I
+/obj/machinery/cryopod/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ var/obj/item/grab/G = used
+ if(!istype(G))
+ return ..()
- if(occupant)
- to_chat(user, "[src] is in use.")
- return
+ if(occupant)
+ to_chat(user, "[src] is in use.")
+ return ITEM_INTERACT_COMPLETE
- if(!ismob(G.affecting))
- return
+ if(!ismob(G.affecting))
+ return ITEM_INTERACT_COMPLETE
- if(!check_occupant_allowed(G.affecting))
- return
+ if(!check_occupant_allowed(G.affecting))
+ return ITEM_INTERACT_COMPLETE
- var/willing = null //We don't want to allow people to be forced into despawning.
- var/mob/living/M = G.affecting
- time_till_despawn = initial(time_till_despawn)
+ var/willing = null //We don't want to allow people to be forced into despawning.
+ var/mob/living/M = G.affecting
+ time_till_despawn = initial(time_till_despawn)
- if(!istype(M) || M.stat == DEAD)
- to_chat(user, "Dead people can not be put into cryo.")
- return
+ if(!istype(M) || M.stat == DEAD)
+ to_chat(user, "Dead people can not be put into cryo.")
+ return ITEM_INTERACT_COMPLETE
- if(M.client)
- if(tgui_alert(M, "Would you like to enter long-term storage?", "Cryosleep", list("Yes", "No")) == "Yes")
- if(!M || !G || !G.affecting)
- return
- willing = willing_time_divisor
- else
- willing = 1
+ if(M.client)
+ if(tgui_alert(M, "Would you like to enter long-term storage?", "Cryosleep", list("Yes", "No")) == "Yes")
+ if(!M || !G || !G.affecting)
+ return ITEM_INTERACT_COMPLETE
+ willing = willing_time_divisor
+ else
+ willing = 1
- if(willing)
+ if(willing)
- visible_message("[user] starts putting [G.affecting.name] into [src].")
+ visible_message("[user] starts putting [G.affecting.name] into [src].")
- if(do_after(user, 20, target = G.affecting))
- if(!M || !G || !G.affecting)
- return
+ if(do_after(user, 20, target = G.affecting))
+ if(!M || !G || !G.affecting)
+ return ITEM_INTERACT_COMPLETE
- if(occupant)
- to_chat(user, "[src] is in use.")
- return
+ if(occupant)
+ to_chat(user, "[src] is in use.")
+ return ITEM_INTERACT_COMPLETE
- take_occupant(M, willing)
+ take_occupant(M, willing)
- else //because why the fuck would you keep going if the mob isn't in the pod
- to_chat(user, "You stop putting [M] into the cryopod.")
- return
+ else //because why the fuck would you keep going if the mob isn't in the pod
+ to_chat(user, "You stop putting [M] into the cryopod.")
+ return ITEM_INTERACT_COMPLETE
- icon_state = occupied_icon_state
+ icon_state = occupied_icon_state
- M.throw_alert("cryopod", /atom/movable/screen/alert/ghost/cryo)
- to_chat(M, "[on_enter_occupant_message]")
- to_chat(M, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")
+ M.throw_alert("cryopod", /atom/movable/screen/alert/ghost/cryo)
+ to_chat(M, "[on_enter_occupant_message]")
+ to_chat(M, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")
- take_occupant(M, willing)
- else
- return ..()
+ take_occupant(M, willing)
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/cryopod/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob)
diff --git a/code/game/machinery/defib_mount.dm b/code/game/machinery/defib_mount.dm
index ea7e911c2f39..6edc2deb731d 100644
--- a/code/game/machinery/defib_mount.dm
+++ b/code/game/machinery/defib_mount.dm
@@ -85,35 +85,36 @@
defib.paddles_on_defib = FALSE
user.put_in_hands(defib.paddles)
-/obj/machinery/defibrillator_mount/attackby__legacy__attackchain(obj/item/I, mob/living/user, params)
- if(istype(I, /obj/item/defibrillator))
+/obj/machinery/defibrillator_mount/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/defibrillator))
if(defib)
to_chat(user, "There's already a defibrillator in [src]!")
- return
- if(I.flags & NODROP || !user.drop_item() || !I.forceMove(src))
- to_chat(user, "[I] is stuck to your hand!")
- return
- user.visible_message("[user] hooks up [I] to [src]!", \
- "You press [I] into the mount, and it clicks into place.")
+ return ITEM_INTERACT_COMPLETE
+ if(used.flags & NODROP || !user.drop_item() || !used.forceMove(src))
+ to_chat(user, "[used] is stuck to your hand!")
+ return ITEM_INTERACT_COMPLETE
+ user.visible_message("[user] hooks up [used] to [src]!", \
+ "You press [used] into the mount, and it clicks into place.")
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
- defib = I
+ defib = used
update_icon(UPDATE_OVERLAYS)
- return
- else if(defib && I == defib.paddles)
+ return ITEM_INTERACT_COMPLETE
+ else if(defib && used == defib.paddles)
user.drop_item()
- return
- var/obj/item/card/id = I.GetID()
+ return ITEM_INTERACT_COMPLETE
+ var/obj/item/card/id = used.GetID()
if(id)
if(check_access(id) || SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED) //anyone can toggle the clamps in red alert!
if(!defib)
to_chat(user, "You can't engage the clamps on a defibrillator that isn't there.")
- return
+ return ITEM_INTERACT_COMPLETE
clamps_locked = !clamps_locked
to_chat(user, "Clamps [clamps_locked ? "" : "dis"]engaged.")
update_icon(UPDATE_OVERLAYS)
else
to_chat(user, "Insufficient access.")
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/defibrillator_mount/wrench_act(mob/user, obj/item/I)
diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm
index 427dc4585a6c..4143930ec3cb 100644
--- a/code/game/machinery/door_control.dm
+++ b/code/game/machinery/door_control.dm
@@ -35,9 +35,9 @@
else
to_chat(user, "Error, no route to host.")
-/obj/machinery/door_control/attackby__legacy__attackchain(obj/item/W, mob/user as mob, params)
- if(istype(W, /obj/item/detective_scanner))
- return
+/obj/machinery/door_control/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/detective_scanner))
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/door_control/emag_act(user as mob)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index e21895e48194..ef09ebfda5b6 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -976,63 +976,67 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
else
to_chat(user, "The door is now in fast mode.")
-/obj/machinery/door/airlock/attackby__legacy__attackchain(obj/item/C, mob/user, params)
+/obj/machinery/door/airlock/item_interaction(mob/living/user, obj/item/used, list/modifiers)
add_fingerprint(user)
if(!headbutt_shock_check(user))
- return
+ return ITEM_INTERACT_COMPLETE
if(panel_open)
switch(security_level)
if(AIRLOCK_SECURITY_NONE)
- if(istype(C, /obj/item/stack/sheet/metal))
- var/obj/item/stack/sheet/metal/S = C
+ if(istype(used, /obj/item/stack/sheet/metal))
+ var/obj/item/stack/sheet/metal/S = used
if(S.get_amount() < 2)
to_chat(user, "You need at least 2 metal sheets to reinforce [src].")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You start reinforcing [src]...")
if(do_after(user, 20, 1, target = src))
if(!panel_open || !S.use(2))
- return
+ return ITEM_INTERACT_COMPLETE
user.visible_message("[user] reinforces \the [src] with metal.",
"You reinforce \the [src] with metal.")
security_level = AIRLOCK_SECURITY_METAL
update_icon()
- return
- else if(istype(C, /obj/item/stack/sheet/plasteel))
- var/obj/item/stack/sheet/plasteel/S = C
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/stack/sheet/plasteel))
+ var/obj/item/stack/sheet/plasteel/S = used
if(S.get_amount() < 2)
to_chat(user, "You need at least 2 plasteel sheets to reinforce [src].")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You start reinforcing [src]...")
if(do_after(user, 20, 1, target = src))
if(!panel_open || !S.use(2))
- return
+ return ITEM_INTERACT_COMPLETE
user.visible_message("[user] reinforces \the [src] with plasteel.",
"You reinforce \the [src] with plasteel.")
security_level = AIRLOCK_SECURITY_PLASTEEL
modify_max_integrity(normal_integrity * AIRLOCK_INTEGRITY_MULTIPLIER)
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_R
update_icon()
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(C, /obj/item/assembly/signaler))
- return interact_with_panel(user)
- else if(istype(C, /obj/item/pai_cable)) // -- TLE
- var/obj/item/pai_cable/cable = C
+ if(istype(used, /obj/item/assembly/signaler))
+ interact_with_panel(used)
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/pai_cable)) // -- TLE
+ var/obj/item/pai_cable/cable = used
cable.plugin(src, user)
- else if(istype(C, /obj/item/paper) || istype(C, /obj/item/photo))
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/paper) || istype(used, /obj/item/photo))
if(note)
to_chat(user, "There's already something pinned to this airlock! Use wirecutters or your hands to remove it.")
- return
- if(!user.transfer_item_to(C, src))
- to_chat(user, "For some reason, you can't attach [C]!")
- return
- C.add_fingerprint(user)
- user.create_log(MISC_LOG, "put [C] on", src)
- user.visible_message("[user] pins [C] to [src].", "You pin [C] to [src].")
- note = C
+ return ITEM_INTERACT_COMPLETE
+ if(!user.transfer_item_to(used, src))
+ to_chat(user, "For some reason, you can't attach [used]!")
+ return ITEM_INTERACT_COMPLETE
+ used.add_fingerprint(user)
+ user.create_log(MISC_LOG, "put [used] on", src)
+ user.visible_message("[user] pins [used] to [src].", "You pin [used] to [src].")
+ note = used
update_icon()
- else
- return ..()
+
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/door/airlock/screwdriver_act(mob/user, obj/item/I)
if(!headbutt_shock_check(user))
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index 686cf95dc02c..96632e6ce7dc 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -200,14 +200,15 @@
DA.update_appearance(UPDATE_NAME|UPDATE_ICON)
qdel(src)
-/obj/machinery/door/airlock/plasma/attackby__legacy__attackchain(obj/item/C, mob/user, params)
- if(C.get_heat() > 300)
+/obj/machinery/door/airlock/plasma/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(used.get_heat() > 300)
message_admins("Plasma airlock ignited by [key_name_admin(user)] in ([x],[y],[z] - JMP)")
log_game("Plasma airlock ignited by [key_name(user)] in ([x],[y],[z])")
investigate_log("was ignited by [key_name(user)]","atmos")
- ignite(C.get_heat())
- else
- return ..()
+ ignite(used.get_heat())
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/door/airlock/plasma/glass
opacity = FALSE
@@ -447,16 +448,17 @@
else
lock(TRUE)
-/obj/machinery/door/airlock/highsecurity/red/attackby__legacy__attackchain(obj/C, mob/user, params)
+/obj/machinery/door/airlock/highsecurity/red/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(!issilicon(user))
if(isElectrified())
if(shock(user, 75))
- return
- if(istype(C, /obj/item/detective_scanner))
- return
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/detective_scanner))
+ return ITEM_INTERACT_COMPLETE
add_fingerprint(user)
+ return ..()
/obj/machinery/door/airlock/highsecurity/red/welder_act(mob/user, obj/item/I)
if(shock_user(user, 75))
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index c89fff93af6a..3363f4f661fe 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -256,13 +256,14 @@
/obj/machinery/door/proc/try_to_crowbar(mob/user, obj/item/I)
return
-/obj/machinery/door/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(HAS_TRAIT(src, TRAIT_CMAGGED) && I.can_clean()) //If the cmagged door is being hit with cleaning supplies, don't open it, it's being cleaned!
- return
+/obj/machinery/door/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(HAS_TRAIT(src, TRAIT_CMAGGED) && used.can_clean()) //If the cmagged door is being hit with cleaning supplies, don't open it, it's being cleaned!
+ return ITEM_INTERACT_SKIP_TO_AFTER_ATTACK
- else if(!(I.flags & NOBLUDGEON) && user.a_intent != INTENT_HARM)
+ else if(!(used.flags & NOBLUDGEON) && user.a_intent != INTENT_HARM)
try_to_activate_door(user)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/door/crowbar_act(mob/user, obj/item/I)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 39ff3baf9723..fbfe39d07dd8 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -124,11 +124,12 @@
"You open [src].")
open(auto_close = FALSE)
-/obj/machinery/door/firedoor/attackby__legacy__attackchain(obj/item/C, mob/user, params)
+/obj/machinery/door/firedoor/item_interaction(mob/living/user, obj/item/used, list/modifiers)
add_fingerprint(user)
if(operating)
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/door/firedoor/try_to_activate_door(mob/user)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 3d5bfb36c1ff..d1e4dc769203 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -313,10 +313,10 @@
operating = NONE
return TRUE
-/obj/machinery/door/window/attackby__legacy__attackchain(obj/item/I, mob/living/user, params)
+/obj/machinery/door/window/item_interaction(mob/living/user, obj/item/used, list/modifiers)
//If it's in the process of opening/closing, ignore the click
if(operating)
- return
+ return ITEM_INTERACT_COMPLETE
add_fingerprint(user)
return ..()
diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm
index 3c3c9998ee99..fe2ea2e65758 100644
--- a/code/game/machinery/doppler_array.dm
+++ b/code/game/machinery/doppler_array.dm
@@ -35,12 +35,12 @@
UnregisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION)
return ..()
-/obj/machinery/doppler_array/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/disk/tech_disk))
- var/obj/item/disk/tech_disk/disk = I
+/obj/machinery/doppler_array/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/disk/tech_disk))
+ var/obj/item/disk/tech_disk/disk = used
disk.load_tech(toxins_tech)
to_chat(user, "You swipe the disk into [src].")
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/doppler_array/wrench_act(mob/user, obj/item/I)
diff --git a/code/game/machinery/dye_generator.dm b/code/game/machinery/dye_generator.dm
index 32891a83821d..29da54caf56d 100644
--- a/code/game/machinery/dye_generator.dm
+++ b/code/game/machinery/dye_generator.dm
@@ -50,17 +50,17 @@
dye_color = temp
set_light(2, l_color = temp)
-/obj/machinery/dye_generator/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/dye_generator/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_unfasten_wrench(user, used, time = 60))
+ return ITEM_INTERACT_COMPLETE
- if(default_unfasten_wrench(user, I, time = 60))
- return
-
- if(istype(I, /obj/item/hair_dye_bottle))
- var/obj/item/hair_dye_bottle/HD = I
+ if(istype(used, /obj/item/hair_dye_bottle))
+ var/obj/item/hair_dye_bottle/HD = used
user.visible_message("[user] fills [HD] up with some dye.","You fill [HD] up with some hair dye.")
HD.dye_color = dye_color
HD.update_icon()
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/dye_generator/obj_break(damage_flag)
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index e943b88119ed..e6b8638e5f05 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -125,26 +125,26 @@ FIRE ALARM
alarm(rand(30/severity, 60/severity))
..()
-/obj/machinery/firealarm/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/firealarm/item_interaction(mob/living/user, obj/item/used, list/modifiers)
add_fingerprint(user)
if(wiresexposed)
- if(buildstage == FIRE_ALARM_UNWIRED)
- if(istype(I, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/coil = I
- if(!coil.use(5))
- to_chat(user, "You need a total of five cables to wire [src]!")
- return
- buildstage = FIRE_ALARM_READY
- playsound(get_turf(src), I.usesound, 50, 1)
- to_chat(user, "You wire [src]!")
- update_icon()
- if(buildstage == FIRE_ALARM_FRAME)
- if(istype(I, /obj/item/firealarm_electronics))
- to_chat(user, "You insert the circuit!")
- qdel(I)
- buildstage = FIRE_ALARM_UNWIRED
- update_icon()
- return
+ if(buildstage == FIRE_ALARM_UNWIRED && istype(used, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/coil = used
+ if(!coil.use(5))
+ to_chat(user, "You need a total of five cables to wire [src]!")
+ return ITEM_INTERACT_COMPLETE
+
+ buildstage = FIRE_ALARM_READY
+ playsound(get_turf(src), used.usesound, 50, 1)
+ to_chat(user, "You wire [src]!")
+ update_icon()
+ else if(buildstage == FIRE_ALARM_FRAME && istype(used, /obj/item/firealarm_electronics))
+ to_chat(user, "You insert the circuit!")
+ qdel(used)
+ buildstage = FIRE_ALARM_UNWIRED
+ update_icon()
+
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/firealarm/crowbar_act(mob/user, obj/item/I)
diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm
index 122dc3f8a625..281d1680205d 100644
--- a/code/game/machinery/floodlight.dm
+++ b/code/game/machinery/floodlight.dm
@@ -90,19 +90,21 @@
set_light(brightness_on)
update_icon(UPDATE_ICON_STATE)
-/obj/machinery/floodlight/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params)
- if(istype(W, /obj/item/stock_parts/cell))
+/obj/machinery/floodlight/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/stock_parts/cell))
if(open)
if(cell)
to_chat(user, "There is a power cell already installed.")
else
- playsound(loc, W.usesound, 50, TRUE)
+ playsound(loc, used.usesound, 50, TRUE)
user.drop_item()
- W.loc = src
- cell = W
+ used.loc = src
+ cell = used
to_chat(user, "You insert the power cell.")
+
update_icon(UPDATE_ICON_STATE)
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/floodlight/screwdriver_act(mob/living/user, obj/item/I)
diff --git a/code/game/machinery/guestpass.dm b/code/game/machinery/guestpass.dm
index 3fe784f09c6b..7a51b67bf8d9 100644
--- a/code/game/machinery/guestpass.dm
+++ b/code/game/machinery/guestpass.dm
@@ -60,19 +60,20 @@
. = ..()
my_terminal_id = ++global_terminal_id
-/obj/machinery/computer/guestpass/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/card/id/nct_data_chip))
- to_chat(user, "[I] does not seem compatible with this terminal!")
- return
- if(istype(I, /obj/item/card/id))
+/obj/machinery/computer/guestpass/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/card/id/nct_data_chip))
+ to_chat(user, "[used] does not seem compatible with this terminal!")
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/card/id))
if(!scan)
if(user.drop_item())
- I.forceMove(src)
- scan = I
+ used.forceMove(src)
+ scan = used
SStgui.update_uis(src)
else
to_chat(user, "There is already ID card inside.")
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/computer/guestpass/proc/get_changeable_accesses()
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index de84be7ef08c..3e1dc638f376 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -60,25 +60,27 @@
bag = null
update_icon(UPDATE_OVERLAYS)
-/obj/machinery/iv_drip/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/reagent_containers/iv_bag))
+/obj/machinery/iv_drip/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/reagent_containers/iv_bag))
if(bag)
to_chat(user, "[src] already has an IV bag!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- return
+ return ITEM_INTERACT_COMPLETE
- I.forceMove(src)
- bag = I
- to_chat(user, "You attach [I] to [src].")
+ used.forceMove(src)
+ bag = used
+ to_chat(user, "You attach [used] to [src].")
update_icon(UPDATE_OVERLAYS)
START_PROCESSING(SSmachines, src)
- else if(bag && istype(I, /obj/item/reagent_containers))
- bag.attackby__legacy__attackchain(I)
- I.afterattack__legacy__attackchain(bag, usr, TRUE)
+ return ITEM_INTERACT_COMPLETE
+ else if(bag && istype(used, /obj/item/reagent_containers))
+ bag.attackby__legacy__attackchain(used)
+ used.afterattack__legacy__attackchain(bag, usr, TRUE)
update_icon(UPDATE_OVERLAYS)
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/iv_drip/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 00fc7a172ce9..259b0ec4ab19 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -9,6 +9,7 @@
atom_say_verb = "beeps"
flags_ricochet = RICOCHET_HARD
receive_ricochet_chance_mod = 0.3
+ new_attack_chain = TRUE
var/stat = 0
/// How is this machine currently passively consuming power?
@@ -33,6 +34,8 @@
/// This is if the machinery is being repaired
var/being_repaired = FALSE
+ new_attack_chain = TRUE
+
/obj/machinery/Initialize(mapload)
. = ..()
GLOB.machines += src
@@ -354,43 +357,45 @@
reregister_machine()
power_change()
-/obj/machinery/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(exchange_parts(user, O))
- return
+/obj/machinery/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(exchange_parts(user, used))
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/stack/nanopaste))
- var/obj/item/stack/nanopaste/N = O
+ if(istype(used, /obj/item/stack/nanopaste))
+ var/obj/item/stack/nanopaste/N = used
if(stat & BROKEN)
to_chat(user, "[src] is too damaged to be fixed with nanopaste!")
- return
+ return ITEM_INTERACT_COMPLETE
if(obj_integrity == max_integrity)
to_chat(user, "[src] is fully intact.")
- return
+ return ITEM_INTERACT_COMPLETE
if(being_repaired)
- return
+ return ITEM_INTERACT_COMPLETE
if(N.get_amount() < 1)
to_chat(user, "You don't have enough to complete this task!")
- return
+ return ITEM_INTERACT_COMPLETE
- to_chat(user, "You start applying [O] to [src].")
+ to_chat(user, "You start applying [used] to [src].")
being_repaired = TRUE
var/result = do_after(user, 3 SECONDS, target = src)
being_repaired = FALSE
if(!result)
- return
+ return ITEM_INTERACT_COMPLETE
if(!N.use(1))
to_chat(user, "You don't have enough to complete this task!") // this is here, as we don't want to use nanopaste until you finish applying
- return
+ return ITEM_INTERACT_COMPLETE
obj_integrity = min(obj_integrity + 50, max_integrity)
- user.visible_message("[user] applied some [O] at [src]'s damaged areas.",\
- "You apply some [O] at [src]'s damaged areas.")
- else
- return ..()
+ user.visible_message("[user] applied some [used] at [src]'s damaged areas.",\
+ "You apply some [used] at [src]'s damaged areas.")
+
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/proc/exchange_parts(mob/user, obj/item/storage/part_replacer/W)
var/shouldplaysound = 0
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
index c14d22c3cad9..765a1fcd22c8 100644
--- a/code/game/machinery/mass_driver.dm
+++ b/code/game/machinery/mass_driver.dm
@@ -83,73 +83,63 @@
anchored = FALSE
var/build = 0
-/obj/machinery/mass_driver_frame/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob)
+/obj/machinery/mass_driver_frame/item_interaction(mob/living/user, obj/item/used, list/modifiers)
switch(build)
if(0) // Loose frame
- if(iswrench(W))
+ if(iswrench(used))
to_chat(user, "You begin to anchor [src] on the floor.")
- playsound(get_turf(src), W.usesound, 50, TRUE)
- if(do_after(user, 1 SECONDS * W.toolspeed, target = src) && (build == 0))
+ playsound(get_turf(src), used.usesound, 50, TRUE)
+ if(do_after(user, 1 SECONDS * used.toolspeed, target = src) && (build == 0))
to_chat(user, "You anchor \the [src]!")
anchored = TRUE
build++
- return TRUE
- return FALSE
-
+ return ITEM_INTERACT_COMPLETE
if(1) // Fixed to the floor
- if(iswrench(W))
+ if(iswrench(used))
to_chat(user, "You begin to de-anchor [src] from the floor.")
- playsound(get_turf(src), W.usesound, 50, TRUE)
- if(do_after(user, 1 SECONDS * W.toolspeed, target = src) && (build == 1))
+ playsound(get_turf(src), used.usesound, 50, TRUE)
+ if(do_after(user, 1 SECONDS * used.toolspeed, target = src) && (build == 1))
build--
anchored = FALSE
to_chat(user, "You de-anchored \the [src]!")
- return TRUE
- return FALSE
-
+ return ITEM_INTERACT_COMPLETE
if(2) // Welded to the floor
- if(iscoil(W))
- var/obj/item/stack/cable_coil/C = W
+ if(iscoil(used))
+ var/obj/item/stack/cable_coil/C = used
to_chat(user, "You start adding cables to [src]...")
playsound(get_turf(src), C.usesound, 50, TRUE)
if(do_after(user, 20 * C.toolspeed, target = src) && (C.get_amount() >= 2) && (build == 2))
C.use(2)
to_chat(user, "You've added cables to \the [src].")
build++
- return TRUE
- return FALSE
-
+ return ITEM_INTERACT_COMPLETE
if(3) // Wired
- if(iswirecutter(W))
+ if(iswirecutter(used))
to_chat(user, "You begin to remove the wiring from [src].")
- if(do_after(user, 1 SECONDS * W.toolspeed, target = src) && (build == 3))
+ if(do_after(user, 1 SECONDS * used.toolspeed, target = src) && (build == 3))
new /obj/item/stack/cable_coil(loc, 2)
- playsound(get_turf(src), W.usesound, 50, 1)
+ playsound(get_turf(src), used.usesound, 50, 1)
to_chat(user, "You've removed the cables from \the [src].")
build--
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(istype(W, /obj/item/stack/rods))
- var/obj/item/stack/rods/R = W
+ if(istype(used, /obj/item/stack/rods))
+ var/obj/item/stack/rods/R = used
to_chat(user, "You begin to complete \the [src]...")
playsound(get_turf(src), R.usesound, 50, 1)
if(do_after(user, 20 * R.toolspeed, target = src) && (R.get_amount() >= 2) && (build == 3))
R.use(2)
to_chat(user, "You've added the grille to \the [src].")
build++
- return TRUE
-
- return FALSE
-
+ return ITEM_INTERACT_COMPLETE
if(4) // Grille in place
- if(iscrowbar(W))
+ if(iscrowbar(used))
to_chat(user, "You begin to pry off the grille from [src]...")
- playsound(get_turf(src), W.usesound, 50, TRUE)
- if(do_after(user, 3 SECONDS * W.toolspeed, target = src) && (build == 4))
+ playsound(get_turf(src), used.usesound, 50, TRUE)
+ if(do_after(user, 3 SECONDS * used.toolspeed, target = src) && (build == 4))
new /obj/item/stack/rods(loc,2)
build--
- return TRUE
- return FALSE
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/game/machinery/merch_vendor.dm b/code/game/machinery/merch_vendor.dm
index 17333ba48f36..853078c9251e 100644
--- a/code/game/machinery/merch_vendor.dm
+++ b/code/game/machinery/merch_vendor.dm
@@ -34,10 +34,10 @@
var/pp = replacetext(replacetext("[merch.typepath]", "/obj/item/", ""), "/", "-")
imagelist[pp] = "[icon2base64(icon(initial(I.icon), initial(I.icon_state), SOUTH, 1))]"
-/obj/machinery/economy/merch/attackby__legacy__attackchain(obj/item/I, mob/user)
- if(isspacecash(I))
- insert_cash(I, user)
- return TRUE
+/obj/machinery/economy/merch/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(isspacecash(used))
+ insert_cash(used, user)
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm
index 5568b941a78f..42c52696eaf1 100644
--- a/code/game/machinery/navbeacon.dm
+++ b/code/game/machinery/navbeacon.dm
@@ -82,12 +82,12 @@
icon_state = "navbeacon[open][invisibility ? "-f" : ""]" // if invisible, set icon to faded version
// in case revealed by T-scanner
-/obj/machinery/navbeacon/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/navbeacon/item_interaction(mob/living/user, obj/item/used, list/modifiers)
var/turf/T = loc
if(T.intact)
- return // prevent intraction when T-scanner revealed
+ return ITEM_INTERACT_COMPLETE // prevent intraction when T-scanner revealed
- else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
+ else if(istype(used, /obj/item/card/id) || istype(used, /obj/item/pda))
if(open)
if(allowed(user))
locked = !locked
@@ -97,8 +97,10 @@
updateDialog()
else
to_chat(user, "You must open the cover first!")
- else
- return ..()
+
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/navbeacon/screwdriver_act(mob/living/user, obj/item/I)
open = !open
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index b01568472112..05d5aae37baa 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -393,11 +393,11 @@ GLOBAL_LIST_EMPTY(turret_icons)
to_chat(user, "You remove the turret but did not manage to salvage anything.")
qdel(src) // qdel
-/obj/machinery/porta_turret/attackby__legacy__attackchain(obj/item/I, mob/user)
+/obj/machinery/porta_turret/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if((stat & BROKEN) && !syndicate)
- return
+ return ITEM_INTERACT_COMPLETE
- else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
+ else if(istype(used, /obj/item/card/id) || istype(used, /obj/item/pda))
if(HasController())
to_chat(user, "Turrets regulated by a nearby turret controller are not unlockable.")
else if(allowed(user))
@@ -407,22 +407,23 @@ GLOBAL_LIST_EMPTY(turret_icons)
else
to_chat(user, "Access denied.")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
if(user.a_intent == INTENT_HELP)
return ..()
+
// otherwise, if the turret was attacked with the intention of harming it:
user.changeNext_move(CLICK_CD_MELEE)
user.do_item_attack_animation()
playsound(src.loc, 'sound/weapons/smash.ogg', 60, 1)
- if(I.force * 0.5 > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off
+
+ //if the force of impact dealt at least 1 damage, the turret gets pissed off
+ if(used.force * 0.5 > 1)
if(!attacked && !emagged)
attacked = TRUE
addtimer(VARSET_CALLBACK(src, attacked, FALSE), 6 SECONDS)
- ..()
-
-
+ return ITEM_INTERACT_SKIP_TO_AFTER_ATTACK
/obj/machinery/porta_turret/attack_animal(mob/living/simple_animal/M)
M.changeNext_move(CLICK_CD_MELEE)
@@ -873,66 +874,63 @@ GLOBAL_LIST_EMPTY(turret_icons)
var/installation = null //the gun type installed
var/gun_charge = 0 //the gun charge of the gun type installed
-
-/obj/machinery/porta_turret_construct/attackby__legacy__attackchain(obj/item/I, mob/user)
+/obj/machinery/porta_turret_construct/item_interaction(mob/living/user, obj/item/used, list/modifiers)
//this is a bit unwieldy but self-explanatory
switch(build_step)
if(0) //first step
- if(iswrench(I) && !anchored)
- playsound(loc, I.usesound, 100, 1)
+ if(iswrench(used) && !anchored)
+ playsound(loc, used.usesound, 100, 1)
to_chat(user, "You secure the external bolts.")
anchored = TRUE
build_step = 1
- return
+ return ITEM_INTERACT_COMPLETE
- else if(I.tool_behaviour == TOOL_CROWBAR && !anchored)
- playsound(loc, I.usesound, 75, 1)
+ else if(used.tool_behaviour == TOOL_CROWBAR && !anchored)
+ playsound(loc, used.usesound, 75, 1)
to_chat(user, "You dismantle the turret construction.")
new /obj/item/stack/sheet/metal( loc, 5)
qdel(src) // qdel
- return
+ return ITEM_INTERACT_COMPLETE
if(1)
- if(istype(I, /obj/item/stack/sheet/metal))
- var/obj/item/stack/sheet/metal/M = I
+ if(istype(used, /obj/item/stack/sheet/metal))
+ var/obj/item/stack/sheet/metal/M = used
if(M.use(2))
to_chat(user, "You add some metal armor to the interior frame.")
build_step = 2
icon_state = "turret_frame2"
else
to_chat(user, "You need two sheets of metal to continue construction.")
- return
+ return ITEM_INTERACT_COMPLETE
- else if(iswrench(I))
- playsound(loc, I.usesound, 75, 1)
+ else if(iswrench(used))
+ playsound(loc, used.usesound, 75, 1)
to_chat(user, "You unfasten the external bolts.")
anchored = FALSE
build_step = 0
- return
-
+ return ITEM_INTERACT_COMPLETE
if(2)
- if(iswrench(I))
- playsound(loc, I.usesound, 100, 1)
+ if(iswrench(used))
+ playsound(loc, used.usesound, 100, 1)
to_chat(user, "You bolt the metal armor into place.")
build_step = 3
- return
+ return ITEM_INTERACT_COMPLETE
if(3)
- if(istype(I, /obj/item/gun/energy)) //the gun installation part
-
+ if(istype(used, /obj/item/gun/energy)) //the gun installation part
if(isrobot(user))
- return
- var/obj/item/gun/energy/E = I //typecasts the item to an energy gun
- if(!user.unequip(I))
- to_chat(user, "\the [I] is stuck to your hand, you cannot put it in \the [src]")
- return
+ return ITEM_INTERACT_COMPLETE
+ var/obj/item/gun/energy/E = used //typecasts the item to an energy gun
+ if(!user.unequip(used))
+ to_chat(user, "\the [used] is stuck to your hand, you cannot put it in \the [src]")
+ return ITEM_INTERACT_COMPLETE
if(!E.can_fit_in_turrets)
- to_chat(user, "[I] will not operate correctly in [src].")
- return
- installation = I.type //installation becomes I.type
+ to_chat(user, "[used] will not operate correctly in [src].")
+ return ITEM_INTERACT_COMPLETE
+ installation = used.type //installation becomes used.type
gun_charge = E.cell.charge //the gun's charge is stored in gun_charge
- to_chat(user, "You add [I] to the turret.")
+ to_chat(user, "You add [used] to the turret.")
if(istype(E, /obj/item/gun/energy/laser/tag/blue))
target_type = /obj/machinery/porta_turret/tag/blue
@@ -942,51 +940,51 @@ GLOBAL_LIST_EMPTY(turret_icons)
target_type = /obj/machinery/porta_turret
build_step = 4
- qdel(I) //delete the gun :( qdel
- return
+ qdel(used) //delete the gun :(
+ return ITEM_INTERACT_COMPLETE
- else if(iswrench(I))
- playsound(loc, I.usesound, 100, 1)
+ else if(iswrench(used))
+ playsound(loc, used.usesound, 100, 1)
to_chat(user, "You remove the turret's metal armor bolts.")
build_step = 2
- return
+ return ITEM_INTERACT_COMPLETE
if(4)
- if(isprox(I))
- if(!user.unequip(I, src))
- to_chat(user, "\the [I] is stuck to your hand, you cannot put it in \the [src]")
- return
+ if(isprox(used))
+ if(!user.unequip(used, src))
+ to_chat(user, "\the [used] is stuck to your hand, you cannot put it in \the [src]")
+ return ITEM_INTERACT_COMPLETE
build_step = 5
- qdel(I) // qdel
+ qdel(used)
to_chat(user, "You add the prox sensor to the turret.")
- return
+ return ITEM_INTERACT_COMPLETE
//attack_hand() removes the gun
if(5)
- return
+ return ITEM_INTERACT_COMPLETE
//screwdriver_act() handles screwing the panel closed
//attack_hand() removes the prox sensor
if(6)
- if(istype(I, /obj/item/stack/sheet/metal))
- var/obj/item/stack/sheet/metal/M = I
+ if(istype(used, /obj/item/stack/sheet/metal))
+ var/obj/item/stack/sheet/metal/M = used
if(M.use(2))
to_chat(user, "You add some metal armor to the exterior frame.")
build_step = 7
else
to_chat(user, "You need two sheets of metal to continue construction.")
- return
+ return ITEM_INTERACT_COMPLETE
if(7)
- if(I.tool_behaviour == TOOL_CROWBAR)
- playsound(loc, I.usesound, 75, 1)
+ if(used.tool_behaviour == TOOL_CROWBAR)
+ playsound(loc, used.usesound, 75, 1)
to_chat(user, "You pry off the turret's exterior armor.")
new /obj/item/stack/sheet/metal(loc, 2)
build_step = 6
- return
+ return ITEM_INTERACT_COMPLETE
- ..()
+ return ..()
/obj/machinery/porta_turret_construct/screwdriver_act(mob/living/user, obj/item/I)
if(build_step != 6 && build_step != 5)
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 0022fbcf0bc4..f8c301d507bb 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -30,45 +30,45 @@
for(var/obj/item/stock_parts/capacitor/C in component_parts)
recharge_coeff = C.rating
-/obj/machinery/recharger/attackby__legacy__attackchain(obj/item/G, mob/user, params)
- var/allowed = is_type_in_list(G, allowed_devices)
+/obj/machinery/recharger/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ var/allowed = is_type_in_list(used, allowed_devices)
if(!allowed)
return ..()
- . = TRUE
-
if(!anchored)
to_chat(user, "[src] isn't connected to anything!")
- return
+ return ITEM_INTERACT_COMPLETE
if(panel_open)
to_chat(user, "Close the maintenance panel first!")
- return
+ return ITEM_INTERACT_COMPLETE
if(charging)
to_chat(user, "There's \a [charging] inserted in [src] already!")
- return
+ return ITEM_INTERACT_COMPLETE
//Checks to make sure he's not in space doing it, and that the area got proper power.
var/area/A = get_area(src)
if(!istype(A) || !A.powernet.has_power(PW_CHANNEL_EQUIPMENT))
- to_chat(user, "[src] blinks red as you try to insert [G].")
- return
+ to_chat(user, "[src] blinks red as you try to insert [used].")
+ return ITEM_INTERACT_COMPLETE
- if(istype(G, /obj/item/gun/energy))
- var/obj/item/gun/energy/E = G
+ if(istype(used, /obj/item/gun/energy))
+ var/obj/item/gun/energy/E = used
if(!E.can_charge)
to_chat(user, "Your gun has no external power connector.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- return
+ return ITEM_INTERACT_COMPLETE
- G.forceMove(src)
- charging = G
+ used.forceMove(src)
+ charging = used
change_power_mode(ACTIVE_POWER_USE)
- using_power = check_cell_needs_recharging(get_cell_from(G))
+ using_power = check_cell_needs_recharging(get_cell_from(used))
update_icon()
+ return ITEM_INTERACT_COMPLETE
+
/obj/machinery/recharger/crowbar_act(mob/user, obj/item/I)
if(panel_open && !charging && default_deconstruction_crowbar(user, I))
return TRUE
diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index 4dfa173b2a72..5701e7a81c38 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -292,44 +292,48 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
if("toggleSilent")
silent = !silent
-
-/obj/machinery/requests_console/attackby__legacy__attackchain(obj/item/I, mob/user)
- if(istype(I, /obj/item/card/id))
- if(inoperable(MAINT))
- return
- if(screen == RCS_MESSAUTH)
- var/obj/item/card/id/T = I
- msgVerified = "Verified by [T.registered_name] ([T.assignment])"
- SStgui.update_uis(src)
- if(screen == RCS_ANNOUNCE)
- var/obj/item/card/id/ID = I
- if(ACCESS_RC_ANNOUNCE in ID.GetAccess())
- announceAuth = TRUE
- announcer.author = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name
- else
- reset_message()
- to_chat(user, "You are not authorized to send announcements.")
- SStgui.update_uis(src)
- if(screen == RCS_SECONDARY)
- var/obj/item/card/id/ID = I
- if(ID)
- secondaryGoalAuth = TRUE
- goalRequester = ID
- has_active_secondary_goal = check_for_active_secondary_goal(goalRequester)
- if(screen == RCS_SHIPPING)
- var/obj/item/card/id/T = I
- msgVerified = "Sender verified as [T.registered_name] ([T.assignment])"
- SStgui.update_uis(src)
- if(istype(I, /obj/item/stamp))
- if(inoperable(MAINT))
- return
- if(screen == RCS_MESSAUTH)
- var/obj/item/stamp/T = I
- msgStamped = "Stamped with the [T.name]"
+/obj/machinery/requests_console/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ var/obj/item/stamp/stamp = used
+ if(istype(stamp))
+ if(screen == RCS_MESSAUTH && !inoperable(MAINT))
+ msgStamped = "Stamped with the [stamp.name]"
SStgui.update_uis(src)
- else
+
+ return ITEM_INTERACT_COMPLETE
+
+ var/obj/item/card/id/id_card = used
+ if(!istype(id_card))
return ..()
+ if(inoperable(MAINT))
+ return ITEM_INTERACT_COMPLETE
+ if(screen == RCS_MESSAUTH)
+ msgVerified = "Verified by [id_card.registered_name] ([id_card.assignment])"
+ SStgui.update_uis(src)
+ return ITEM_INTERACT_COMPLETE
+ if(screen == RCS_ANNOUNCE)
+ if(ACCESS_RC_ANNOUNCE in id_card.GetAccess())
+ announceAuth = TRUE
+ announcer.author = id_card.assignment ? "[id_card.assignment] [id_card.registered_name]" : id_card.registered_name
+ else
+ reset_message()
+ to_chat(user, "You are not authorized to send announcements.")
+ SStgui.update_uis(src)
+ return ITEM_INTERACT_COMPLETE
+ if(screen == RCS_SECONDARY)
+ secondaryGoalAuth = TRUE
+ goalRequester = id_card
+ has_active_secondary_goal = check_for_active_secondary_goal(goalRequester)
+
+ return ITEM_INTERACT_COMPLETE
+ if(screen == RCS_SHIPPING)
+ msgVerified = "Sender verified as [id_card.registered_name] ([id_card.assignment])"
+ SStgui.update_uis(src)
+
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
+
/obj/machinery/requests_console/proc/reset_message(mainmenu = FALSE)
message = ""
recipient = ""
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index 2a8a67c77889..95c512659d38 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -232,17 +232,18 @@
else
to_chat(user, "The device must first be secured to the floor.")
-/obj/machinery/shieldgen/attackby__legacy__attackchain(obj/item/I as obj, mob/user as mob, params)
- if(istype(I, /obj/item/card/emag))
+/obj/machinery/shieldgen/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/card/emag))
malfunction = TRUE
update_icon(UPDATE_ICON_STATE)
- else if(istype(I, /obj/item/stack/cable_coil) && malfunction && is_open)
- var/obj/item/stack/cable_coil/coil = I
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/stack/cable_coil) && malfunction && is_open)
+ var/obj/item/stack/cable_coil/coil = used
to_chat(user, "You begin to replace the wires.")
if(do_after(user, 30 * coil.toolspeed, target = src))
if(!src || !coil)
- return
+ return ITEM_INTERACT_COMPLETE
coil.use(1)
health = max_health
malfunction = FALSE
@@ -250,15 +251,17 @@
to_chat(user, "You repair [src]!")
update_icon(UPDATE_ICON_STATE)
- else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/card/id) || istype(used, /obj/item/pda))
if(allowed(user))
locked = !locked
to_chat(user, "The controls are now [locked ? "locked." : "unlocked."]")
else
to_chat(user, "Access denied.")
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/shieldgen/screwdriver_act(mob/user, obj/item/I)
. = TRUE
@@ -427,17 +430,18 @@
var/list/L = active_shields["[direction]"]
L -= SW
-/obj/machinery/shieldwallgen/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/card/id)||istype(I, /obj/item/pda))
+/obj/machinery/shieldwallgen/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/card/id)||istype(used, /obj/item/pda))
if(allowed(user))
locked = !locked
to_chat(user, "Controls are now [locked ? "locked." : "unlocked."]")
else
to_chat(user, "Access denied.")
- else
- add_fingerprint(user)
- ..()
+ return ITEM_INTERACT_COMPLETE
+
+ add_fingerprint(user)
+ return ..()
/obj/machinery/shieldwallgen/wrench_act(mob/user, obj/item/I)
. = TRUE
@@ -583,7 +587,7 @@
phaseout()
return ..()
-/obj/machinery/shieldwall/syndicate/attackby__legacy__attackchain(obj/item/W, mob/user, params)
+/obj/machinery/shieldwall/syndicate/item_interaction(mob/living/user, obj/item/used, list/modifiers)
phaseout()
return ..()
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index ac81b6e71d36..e534e3b47395 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -50,28 +50,25 @@
cell.emp_act(severity)
..(severity)
-/obj/machinery/space_heater/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/stock_parts/cell))
- if(open)
- if(cell)
- to_chat(user, "There is already a power cell inside.")
- return
- else
- // insert cell
- var/obj/item/stock_parts/cell/C = user.get_active_hand()
- if(istype(C))
- if(user.drop_item())
- cell = C
- C.forceMove(src)
- C.add_fingerprint(user)
+/obj/machinery/space_heater/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(!istype(used, /obj/item/stock_parts/cell))
+ return ..()
- user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].")
- else
- to_chat(user, "The hatch must be open to insert a power cell.")
- return
+ if(!open)
+ to_chat(user, "The hatch must be open to insert a power cell.")
+ return ITEM_INTERACT_COMPLETE
+ if(cell)
+ to_chat(user, "There is already a power cell inside.")
+ return ITEM_INTERACT_COMPLETE
else
- return ..()
+ // insert cell
+ var/obj/item/stock_parts/cell/C = user.get_active_hand()
+ C.add_fingerprint(user)
+ user.visible_message("[user] inserts a power cell into [src].",\
+ "You insert the power cell into [src].")
+
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/space_heater/screwdriver_act(mob/user, obj/item/I)
. = TRUE
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 69c12c767f8c..b47552df0ab9 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -317,10 +317,10 @@
. += "[base_icon_state]_[occupant ? "body" : "ready"]"
-/obj/machinery/suit_storage_unit/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/suit_storage_unit/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(shocked)
if(shock(user, 100))
- return
+ return ITEM_INTERACT_COMPLETE
if(!is_operational())
if(user.a_intent != INTENT_HELP)
return ..()
@@ -328,18 +328,19 @@
to_chat(usr, "Close the maintenance panel first.")
else
to_chat(usr, "The unit is not operational.")
- return
+ return ITEM_INTERACT_COMPLETE
if(panel_open)
wires.Interact(user)
- return
+ return ITEM_INTERACT_COMPLETE
if(state_open)
- if(store_item(I, user))
+ if(store_item(used, user))
update_icon(UPDATE_OVERLAYS)
SStgui.update_uis(src)
- to_chat(user, "You load [I] into the storage compartment.")
+ to_chat(user, "You load [used] into the storage compartment.")
else
- to_chat(user, "You can't fit [I] into [src]!")
- return
+ to_chat(user, "You can't fit [used] into [src]!")
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/suit_storage_unit/crowbar_act(mob/living/user, obj/item/I)
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 0324d2e41d27..d0841d27591f 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -114,21 +114,24 @@
else
. = timer_set
-/obj/machinery/syndicatebomb/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/assembly/signaler))
+/obj/machinery/syndicatebomb/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/assembly/signaler))
if(open_panel)
wires.Interact(user)
- else if(istype(I, /obj/item/bombcore))
+
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/bombcore))
if(!payload)
if(!user.drop_item())
- return
- payload = I
+ return ITEM_INTERACT_COMPLETE
+ payload = used
to_chat(user, "You place [payload] into [src].")
payload.forceMove(src)
else
to_chat(user, "[payload] is already loaded into [src], you'll have to remove it first.")
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/syndicatebomb/wrench_act(mob/user, obj/item/I)
if(!can_unanchor)
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index d8b133a3eb2c..b1a030c91b9b 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -47,17 +47,18 @@
power_station = locate(/obj/machinery/teleport/station, orange(1, src))
return power_station
-/obj/machinery/computer/teleporter/attackby__legacy__attackchain(obj/item/I, mob/living/user, params)
- if(istype(I, /obj/item/gps))
- var/obj/item/gps/L = I
+/obj/machinery/computer/teleporter/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/gps))
+ var/obj/item/gps/L = used
if(L.locked_location && !(stat & (NOPOWER|BROKEN)))
if(!user.transfer_item_to(L, src))
- to_chat(user, "[I] is stuck to your hand, you cannot put it in [src]")
- return
+ to_chat(user, "[used] is stuck to your hand, you cannot put it in [src]")
+ return ITEM_INTERACT_COMPLETE
locked = L
to_chat(user, "You insert the GPS device into [src]'s slot.")
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/computer/teleporter/emag_act(mob/user)
if(!emagged)
@@ -641,16 +642,16 @@
teleporter_console = null
return ..()
-/obj/machinery/teleport/station/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(panel_open && istype(I, /obj/item/circuitboard/teleporter_perma))
+/obj/machinery/teleport/station/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(panel_open && istype(used, /obj/item/circuitboard/teleporter_perma))
if(!teleporter_console)
to_chat(user, "[src] is not linked to a teleporter console.")
- return
+ return ITEM_INTERACT_COMPLETE
- var/obj/item/circuitboard/teleporter_perma/C = I
+ var/obj/item/circuitboard/teleporter_perma/C = used
C.target = teleporter_console.target
to_chat(user, "You copy the targeting information from [src] to [C].")
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm
index cbd4bc6bc3f5..70f06f79b0dd 100644
--- a/code/game/machinery/transformer.dm
+++ b/code/game/machinery/transformer.dm
@@ -313,17 +313,17 @@
domutcheck(H, MUTCHK_FORCED)
H.update_mutations()
-/obj/machinery/transformer/gene_applier/attackby__legacy__attackchain(obj/item/I, mob/living/user, params)
- if(istype(I, /obj/item/disk/data))
+/obj/machinery/transformer/gene_applier/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/disk/data))
if(locked)
to_chat(user, "Access Denied.")
- return FALSE
- var/obj/item/disk/data/D = I
+ return ITEM_INTERACT_COMPLETE
+ var/obj/item/disk/data/D = used
if(!D.buf)
to_chat(user, "Error: No data found.")
- return FALSE
+ return ITEM_INTERACT_COMPLETE
template = D.buf.dna.Clone()
to_chat(user, "Upload of gene template for '[template.real_name]' complete!")
- return TRUE
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm
index bdc87cd7d9c5..8b8b2b601072 100644
--- a/code/game/machinery/turret_control.dm
+++ b/code/game/machinery/turret_control.dm
@@ -106,18 +106,19 @@
return FALSE
-/obj/machinery/turretid/attackby__legacy__attackchain(obj/item/W, mob/user)
+/obj/machinery/turretid/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(stat & BROKEN)
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(W, /obj/item/card/id)||istype(W, /obj/item/pda))
+ if(istype(used, /obj/item/card/id)||istype(used, /obj/item/pda))
if(src.allowed(usr))
if(emagged)
to_chat(user, "The turret control is unresponsive.")
else
locked = !locked
to_chat(user, "You [ locked ? "lock" : "unlock"] the panel.")
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/turretid/emag_act(user as mob)
diff --git a/code/game/machinery/vendors/vending.dm b/code/game/machinery/vendors/vending.dm
index 079765b8ea5b..89a3ea1d28e7 100644
--- a/code/game/machinery/vendors/vending.dm
+++ b/code/game/machinery/vendors/vending.dm
@@ -338,25 +338,25 @@
if(user && (!Adjacent(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)))
return COMPONENT_BLOCK_UNTILT
-/obj/machinery/economy/vending/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/economy/vending/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(tilted)
if(user.a_intent == INTENT_HELP)
to_chat(user, "[src] is tipped over and non-functional! You'll need to right it first.")
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
- if(isspacecash(I))
- insert_cash(I, user)
- return
- if(istype(I, /obj/item/coin))
+ if(isspacecash(used))
+ insert_cash(used, user)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/coin))
to_chat(user, "[src] does not accept coins.")
- return
- if(refill_canister && istype(I, refill_canister))
+ return ITEM_INTERACT_COMPLETE
+ if(refill_canister && istype(used, refill_canister))
if(stat & (BROKEN|NOPOWER))
to_chat(user, "[src] does not respond.")
- return
+ return ITEM_INTERACT_COMPLETE
- var/obj/item/vending_refill/canister = I
+ var/obj/item/vending_refill/canister = ITEM_INTERACT_COMPLETE
var/transferred = restock(canister)
if(!transferred && !canister.get_part_rating()) // It transferred no products and has no products left, thus it is empty
to_chat(user, "[canister] is empty!")
@@ -364,13 +364,17 @@
to_chat(user, "You loaded [transferred] items in [src].")
else // Nothing transferred, parts are still left, nothing to restock!
to_chat(user, "There's nothing to restock!")
- return
+ return ITEM_INTERACT_COMPLETE
- if(item_slot_check(user, I))
- insert_item(user, I)
- return
- . = ..()
- if(tiltable && !tilted && I.force)
+ if(item_slot_check(user, used))
+ insert_item(user, used)
+ return ITEM_INTERACT_COMPLETE
+
+/obj/machinery/economy/vending/attacked_by(obj/item/attacker, mob/living/user)
+ if(..())
+ return FINISH_ATTACK
+
+ if(tiltable && !tilted && attacker.force)
if(resistance_flags & INDESTRUCTIBLE)
// no goodies, but also no tilts
return
diff --git a/code/game/machinery/wall_holosign.dm b/code/game/machinery/wall_holosign.dm
index a66a4f98a274..3e89ef7c651d 100644
--- a/code/game/machinery/wall_holosign.dm
+++ b/code/game/machinery/wall_holosign.dm
@@ -49,9 +49,9 @@
/obj/machinery/holosign_switch/attack_ai(mob/user as mob)
return src.attack_hand(user)
-/obj/machinery/holosign_switch/attackby__legacy__attackchain(obj/item/W, mob/user as mob, params)
- if(istype(W, /obj/item/detective_scanner))
- return
+/obj/machinery/holosign_switch/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/detective_scanner))
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/holosign_switch/attack_hand(mob/user as mob)
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index 61ebcb67676d..534800a8d103 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -83,28 +83,28 @@
return
toggle_door()
-
-/obj/machinery/washing_machine/attackby__legacy__attackchain(obj/item/W, mob/user, params)
+/obj/machinery/washing_machine/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(user.a_intent == INTENT_HARM)
return ..()
- if(default_unfasten_wrench(user, W))
- return
- if(default_deconstruction_screwdriver(user, icon_state, icon_state, W))
+ if(default_unfasten_wrench(user, used))
+ return ITEM_INTERACT_COMPLETE
+ if(default_deconstruction_screwdriver(user, icon_state, icon_state, used))
update_appearance(UPDATE_ICON_STATE)
- return
- if(default_deconstruction_crowbar(user, W, FALSE))
- return
- if(istype(W, /obj/item/soap))
+ return ITEM_INTERACT_COMPLETE
+ if(default_deconstruction_crowbar(user, used, FALSE))
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/soap))
return ..() // need to be able to clean washing machine without putting stuff into the washing machine :D
- if(istype(W, /obj/item/grab))
- var/obj/item/grab/G = W
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/G = used
if(isliving(G.assailant))
if(attempt_insert(user, G.affecting))
qdel(G)
- return
- if(istype(W))
- if(attempt_insert(user, W))
- return
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used))
+ if(attempt_insert(user, used))
+ return ITEM_INTERACT_COMPLETE
+
return ..()
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 9ace87b74229..3c481ae663a1 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -310,13 +310,12 @@
return FALSE
return TRUE
-// Interaction code
-/obj/machinery/mecha_part_fabricator/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W))
- return
+/obj/machinery/mecha_part_fabricator/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", used))
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_crowbar(user, W))
- return TRUE
+ if(default_deconstruction_crowbar(user, used))
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/game/objects/items/weapons/stock_parts.dm b/code/game/objects/items/weapons/stock_parts.dm
index 359802da3d5c..469b32bf7420 100644
--- a/code/game/objects/items/weapons/stock_parts.dm
+++ b/code/game/objects/items/weapons/stock_parts.dm
@@ -47,19 +47,31 @@
if(!istype(M))
return ..()
- if(!proximity_flag && !works_from_distance)
- return
-
- if(get_dist(src, M) <= (user.client.maxview() + 2))
- if(M.component_parts)
- M.exchange_parts(user, src)
- if(works_from_distance)
- user.Beam(M, icon_state="rped_upgrade", icon='icons/effects/effects.dmi', time=5)
+ if(!proximity_flag)
+ if(!works_from_distance)
+ return
+ if(get_dist(src, M) <= (user.client.maxview() + 2))
+ return
+
+ if(M.component_parts)
+ M.exchange_parts(user, src)
+ if(works_from_distance)
+ user.Beam(M, icon_state="rped_upgrade", icon='icons/effects/effects.dmi', time=5)
else
message_admins("\[EXPLOIT] [key_name_admin(user)] attempted to upgrade machinery with a BRPED via a camera console (attempted range exploit).")
playsound(src, 'sound/machines/synth_no.ogg', 15, TRUE)
to_chat(user, "ERROR: [M] is out of [src]'s range!")
+/obj/item/storage/part_replacer/tier4/populate_contents()
+ for(var/amount in 1 to 30)
+ new /obj/item/stock_parts/capacitor/quadratic(src)
+ new /obj/item/stock_parts/manipulator/femto(src)
+ new /obj/item/stock_parts/matter_bin/bluespace(src)
+ new /obj/item/stock_parts/micro_laser/quadultra(src)
+ new /obj/item/stock_parts/scanning_module/triphasic(src)
+ new /obj/item/stock_parts/cell/bluespace(src)
+ new /obj/item/reagent_containers/glass/beaker/bluespace(src)
+
////////////////////////////////////////
// Bluespace Part Replacer
////////////////////////////////////////
diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm
index d68b48bb0a72..1fc97e43a600 100644
--- a/code/game/objects/structures/barsign.dm
+++ b/code/game/objects/structures/barsign.dm
@@ -178,12 +178,12 @@
return
attack_hand(user)
-/obj/machinery/barsign/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/barsign/item_interaction(mob/living/user, obj/item/used, list/modifiers)
switch(build_stage)
// Inserting the electronics/circuit
if(BARSIGN_FRAME)
- if(istype(I, /obj/item/barsign_electronics))
- var/obj/item/barsign_electronics/electronic = I
+ if(istype(used, /obj/item/barsign_electronics))
+ var/obj/item/barsign_electronics/electronic = used
if(electronic.destroyed)
emagged = TRUE
else
@@ -196,37 +196,37 @@
qdel(electronic)
build_stage = BARSIGN_CIRCUIT
update_icon()
- playsound(get_turf(src), I.usesound, 50, TRUE)
+ playsound(get_turf(src), used.usesound, 50, TRUE)
add_fingerprint(user)
- return
+ return ITEM_INTERACT_COMPLETE
// Wiring the bar sign
if(BARSIGN_CIRCUIT)
- if(istype(I, /obj/item/stack/cable_coil))
- if(!I.use(5))
+ if(istype(used, /obj/item/stack/cable_coil))
+ if(!used.use(5))
to_chat(user, "You need a total of five cables to wire [src]!")
- return
+ return ITEM_INTERACT_COMPLETE
stat &= ~EMPED
build_stage = BARSIGN_WIRED
update_icon()
- playsound(get_turf(src), I.usesound, 50, TRUE)
+ playsound(get_turf(src), used.usesound, 50, TRUE)
to_chat(user, "You wire [src]!")
power_state = IDLE_POWER_USE
add_fingerprint(user)
- return
+ return ITEM_INTERACT_COMPLETE
// Placing in the glass
if(BARSIGN_WIRED)
- if(istype(I, /obj/item/stack/sheet/glass))
- if(!I.use(2))
+ if(istype(used, /obj/item/stack/sheet/glass))
+ if(!used.use(2))
to_chat(user, "You need at least 2 sheets of glass for this!")
- return
+ return ITEM_INTERACT_COMPLETE
build_stage = BARSIGN_COMPLETE
- playsound(get_turf(src), I.usesound, 50, TRUE)
+ playsound(get_turf(src), used.usesound, 50, TRUE)
obj_integrity = max_integrity
if(stat & BROKEN)
stat &= ~BROKEN
set_sign(new /datum/barsign/hiddensigns/signoff)
add_fingerprint(user)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/barsign/proc/pick_sign(mob/user)
diff --git a/code/game/objects/structures/grey_autocloner.dm b/code/game/objects/structures/grey_autocloner.dm
index d11afe9a220c..294197204608 100644
--- a/code/game/objects/structures/grey_autocloner.dm
+++ b/code/game/objects/structures/grey_autocloner.dm
@@ -24,12 +24,14 @@
clonemind = null
return ..()
-/obj/machinery/grey_autocloner/attackby__legacy__attackchain(obj/item/bio_chip_implanter/implant, mob/user, params)
+/obj/machinery/grey_autocloner/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ var/obj/item/bio_chip_implanter/implant = used
if(!istype(implant) || !(istype(implant.imp, /obj/item/bio_chip/grey_autocloner)))
return ..()
var/obj/item/bio_chip/grey_autocloner/autoclone = implant.imp
autoclone.linked = src
atom_say("Link confirmed!")
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/grey_autocloner/proc/growclone(datum/dna2_record/R)
if(attempting || stat & (NOPOWER|BROKEN))
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 24e67bd26a1c..2bd57402faae 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -346,9 +346,11 @@
if(istype(T) && !T.density)
T.MakeSlippery(TURF_WET_WATER, 5 SECONDS)
-/obj/machinery/shower/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(I.type == /obj/item/analyzer)
+/obj/machinery/shower/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/analyzer))
to_chat(user, "The water temperature seems to be [current_temperature].")
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/shower/wrench_act(mob/user, obj/item/I)
diff --git a/code/modules/arcade/arcade_base.dm b/code/modules/arcade/arcade_base.dm
index dbf3db54bf48..eaa1db69004a 100644
--- a/code/modules/arcade/arcade_base.dm
+++ b/code/modules/arcade/arcade_base.dm
@@ -56,18 +56,18 @@
to_chat(user, "Someone else is already playing this machine, please wait your turn!")
return
-/obj/machinery/economy/arcade/attackby__legacy__attackchain(obj/item/O, mob/user, params)
+/obj/machinery/economy/arcade/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(!freeplay)
- if(isspacecash(O))
- insert_cash(O, user, token_price)
+ if(isspacecash(used))
+ insert_cash(used, user, token_price)
if(pay_with_cash(token_price, "Arcade Token Purchase", "DonkBook Gaming", user, account_database.vendor_account))
tokens += 1
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/card/id))
- if(pay_with_card(O, token_price, "Arcade Token Purchase", "DonkBook Gaming", user, account_database.vendor_account))
+ if(istype(used, /obj/item/card/id))
+ if(pay_with_card(used, token_price, "Arcade Token Purchase", "DonkBook Gaming", user, account_database.vendor_account))
tokens += 1
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/arcade/prize_counter.dm b/code/modules/arcade/prize_counter.dm
index 3bab7848f10a..8c787c3435ce 100644
--- a/code/modules/arcade/prize_counter.dm
+++ b/code/modules/arcade/prize_counter.dm
@@ -79,18 +79,18 @@
else
icon_state = "prize_counter-on"
-/obj/machinery/prize_counter/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/stack/tickets))
- var/obj/item/stack/tickets/T = O
+/obj/machinery/prize_counter/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/stack/tickets))
+ var/obj/item/stack/tickets/T = used
if(user.drop_item_to_ground(T))
tickets += T.amount
SStgui.update_uis(src)
qdel(T)
else
to_chat(user, "\The [T] seems stuck to your hand!")
- return
+ return ITEM_INTERACT_COMPLETE
if(panel_open)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index 795772f5d1a6..5216ac330ebd 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -998,14 +998,14 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
playsound(src.loc, 'sound/effects/sparks4.ogg', 50, TRUE)
return TRUE
-/obj/machinery/alarm/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/alarm/item_interaction(mob/living/user, obj/item/used, list/modifiers)
add_fingerprint(user)
switch(buildstage)
if(AIR_ALARM_READY)
- if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))// trying to unlock the interface with an ID card
+ if(istype(used, /obj/item/card/id) || istype(used, /obj/item/pda))// trying to unlock the interface with an ID card
if(stat & (NOPOWER|BROKEN))
- return
+ return ITEM_INTERACT_COMPLETE
if(allowed(user) && !wires.is_cut(WIRE_IDSCAN))
locked = !locked
@@ -1013,14 +1013,15 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
SStgui.update_uis(src)
else
to_chat(user, "Access denied.")
- return
+
+ return ITEM_INTERACT_COMPLETE
if(AIR_ALARM_UNWIRED)
- if(iscoil(I))
- var/obj/item/stack/cable_coil/coil = I
+ if(iscoil(used))
+ var/obj/item/stack/cable_coil/coil = used
if(coil.get_amount() < 5)
to_chat(user, "You need more cable for this!")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You wire [src]!")
playsound(get_turf(src), coil.usesound, 50, 1)
@@ -1030,15 +1031,15 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
wiresexposed = TRUE
update_icon(UPDATE_ICON_STATE | UPDATE_OVERLAYS)
first_run()
- return
+ return ITEM_INTERACT_COMPLETE
if(AIR_ALARM_FRAME)
- if(istype(I, /obj/item/airalarm_electronics))
- to_chat(user, "You insert [I] into [src].")
- playsound(get_turf(src), I.usesound, 50, 1)
- qdel(I)
+ if(istype(used, /obj/item/airalarm_electronics))
+ to_chat(user, "You insert [used] into [src].")
+ playsound(get_turf(src), used.usesound, 50, TRUE)
+ qdel(used)
buildstage = 1
update_icon(UPDATE_ICON_STATE)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/alarm/crowbar_act(mob/user, obj/item/I)
diff --git a/code/modules/atmospherics/machinery/atmospherics.dm b/code/modules/atmospherics/machinery/atmospherics.dm
index 945b1a6c4daf..988048aaf556 100644
--- a/code/modules/atmospherics/machinery/atmospherics.dm
+++ b/code/modules/atmospherics/machinery/atmospherics.dm
@@ -256,11 +256,12 @@ Pipelines + Other Objects -> Pipe network
return FALSE
//(De)construction
-/obj/machinery/atmospherics/attackby__legacy__attackchain(obj/item/W, mob/user)
+/obj/machinery/atmospherics/item_interaction(mob/living/user, obj/item/used, list/modifiers)
var/turf/T = get_turf(src)
if(T.transparent_floor)
to_chat(user, "You can't interact with something that's under the floor!")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
+
return ..()
//Called when an atmospherics object is unwrenched while having a large pressure difference
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/binary_atmos_base.dm b/code/modules/atmospherics/machinery/components/binary_devices/binary_atmos_base.dm
index 5120a43c0ab8..7a8d2465e1f6 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/binary_atmos_base.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/binary_atmos_base.dm
@@ -15,6 +15,8 @@
var/datum/pipeline/parent1
var/datum/pipeline/parent2
+ new_attack_chain = TRUE
+
/obj/machinery/atmospherics/binary/New()
..()
switch(dir)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
index 16f7ff116e73..c6c135990f95 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
@@ -157,8 +157,9 @@ Thus, the two variables affect pump operation are set in New():
return
update_icon()
-/obj/machinery/atmospherics/binary/pump/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(is_pen(W))
- rename_interactive(user, W)
- return TRUE
+/obj/machinery/atmospherics/binary/bump/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(is_pen(used))
+ rename_interactive(user, used)
+ return ITEM_INTERACT_COMPLETE
+
return ..()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
index a39e69c38732..0bae5c086d31 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
@@ -153,8 +153,9 @@ Thus, the two variables affect pump operation are set in New():
return
update_icon()
-/obj/machinery/atmospherics/binary/volume_pump/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(is_pen(W))
- rename_interactive(user, W)
- return TRUE
+/obj/machinery/atmospherics/binary/volume_pump/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(is_pen(used))
+ rename_interactive(user, used)
+ return ITEM_INTERACT_COMPLETE
+
return ..()
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
index 8ac8021ead3e..658862ea7836 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
@@ -227,12 +227,12 @@
if(.)
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
-/obj/machinery/atmospherics/trinary/filter/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(is_pen(W))
- rename_interactive(user, W)
- return
- else
- return ..()
+/obj/machinery/atmospherics/trinary/filter/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(is_pen(used))
+ rename_interactive(user, used)
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
#undef FILTER_NOTHING
#undef FILTER_TOXINS
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index 977ce8e4d18a..99d814a82192 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -201,9 +201,9 @@
if(.)
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
-/obj/machinery/atmospherics/trinary/mixer/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(is_pen(W))
- rename_interactive(user, W)
- return
- else
- return ..()
+/obj/machinery/atmospherics/trinary/mixer/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(is_pen(used))
+ rename_interactive(user, used)
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 6ed09eda30bc..3fffb34b925b 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -298,41 +298,42 @@
add_fingerprint(usr)
-/obj/machinery/atmospherics/unary/cryo_cell/attackby__legacy__attackchain(obj/item/G, mob/user, params)
- if(istype(G, /obj/item/reagent_containers/glass) && user.a_intent != INTENT_HARM)
- var/obj/item/reagent_containers/B = G
+/obj/machinery/atmospherics/unary/cryo_cell/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/reagent_containers/glass) && user.a_intent != INTENT_HARM)
+ var/obj/item/reagent_containers/B = used
if(beaker)
to_chat(user, "A beaker is already loaded into the machine.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
to_chat(user, "[B] is stuck to you!")
- return
+ return ITEM_INTERACT_COMPLETE
B.forceMove(src)
beaker = B
add_attack_logs(user, null, "Added [B] containing [B.reagents.log_list()] to a cryo cell at [COORD(src)]")
user.visible_message("[user] adds \a [B] to [src]!", "You add \a [B] to [src]!")
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(G, /obj/item/grab))
- var/obj/item/grab/GG = G
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/GG = used
if(panel_open)
to_chat(user, "Close the maintenance panel first.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!ismob(GG.affecting))
- return
+ return ITEM_INTERACT_COMPLETE
if(GG.affecting.has_buckled_mobs()) //mob attached to us
to_chat(user, "[GG.affecting] will not fit into [src] because [GG.affecting.p_they()] [GG.affecting.p_have()] a slime latched onto [GG.affecting.p_their()] head.")
- return
+ return ITEM_INTERACT_COMPLETE
var/mob/M = GG.affecting
if(put_mob(M))
qdel(GG)
- return
+
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
index 412bf1b2e24a..630da74b8e63 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
@@ -186,17 +186,17 @@
pipe_image.plane = ABOVE_HUD_PLANE
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, TRUE)
-/obj/machinery/atmospherics/unary/vent_pump/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/paper))
+/obj/machinery/atmospherics/unary/vent_pump/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/paper))
if(!welded)
if(open)
- user.drop_item(W)
- W.forceMove(src)
+ user.drop_item(used)
+ used.forceMove(src)
if(!open)
to_chat(user, "You can't shove that down there when it is closed")
else
to_chat(user, "The vent is welded.")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
index 5fa57bd2e723..9843b487fad9 100644
--- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
+++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
@@ -120,12 +120,12 @@
update_icon()
return TRUE
-/obj/machinery/atmospherics/portable/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/tank))
+/obj/machinery/atmospherics/portable/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/tank))
if(!(stat & BROKEN))
if(!user.drop_item())
- return
- var/obj/item/tank/T = W
+ return ITEM_INTERACT_COMPLETE
+ var/obj/item/tank/T = used
user.drop_item()
if(holding_tank)
to_chat(user, "[holding_tank ? "In one smooth motion you pop [holding_tank] out of [src]'s connector and replace it with [T]" : "You insert [T] into [src]"].")
@@ -133,7 +133,7 @@
T.loc = src
holding_tank = T
update_icon()
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/atmospherics/portable/wrench_act(mob/user, obj/item/I)
@@ -157,9 +157,9 @@
else
to_chat(user, "Nothing happens.")
-/obj/machinery/atmospherics/portable/attacked_by__legacy__attackchain(obj/item/I, mob/user)
- if(I.force < 10 && !(stat & BROKEN))
+/obj/machinery/atmospherics/portable/attacked_by(obj/item/attacker, mob/living/user)
+ if(attacker.force < 10 && !(stat & BROKEN))
take_damage(0)
else
add_fingerprint(user)
- ..()
+ return ..()
diff --git a/code/modules/economy/economy_machinery/account_terminal.dm b/code/modules/economy/economy_machinery/account_terminal.dm
index f3576f42edff..f125ade29790 100644
--- a/code/modules/economy/economy_machinery/account_terminal.dm
+++ b/code/modules/economy/economy_machinery/account_terminal.dm
@@ -24,9 +24,10 @@
/obj/machinery/computer/account_database/proc/reconnect_database()
account_db = GLOB.station_money_database
-/obj/machinery/computer/account_database/attackby__legacy__attackchain(obj/O, mob/user, params)
- if(ui_login_attackby(O, user))
- return
+/obj/machinery/computer/account_database/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(ui_login_attackby(used, user))
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/computer/account_database/attack_hand(mob/user)
diff --git a/code/modules/economy/economy_machinery/atm.dm b/code/modules/economy/economy_machinery/atm.dm
index b55c28d3d74e..c21ed7772584 100644
--- a/code/modules/economy/economy_machinery/atm.dm
+++ b/code/modules/economy/economy_machinery/atm.dm
@@ -77,17 +77,15 @@
/obj/machinery/economy/atm/attack_ghost(mob/user)
ui_interact(user)
-/obj/machinery/economy/atm/attackby__legacy__attackchain(obj/item/I, mob/user)
- if(istype(I, /obj/item/card/id))
+/obj/machinery/economy/atm/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/card/id))
if(has_power())
- handle_id_insert(I, user)
- return TRUE
+ handle_id_insert(used, user)
+ return ITEM_INTERACT_COMPLETE
else if(authenticated_account)
- if(istype(I, /obj/item/stack/spacecash))
- if(!has_power())
- return
- insert_cash(I, user)
- return TRUE
+ if(istype(used, /obj/item/stack/spacecash) && has_power())
+ insert_cash(used, user)
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/fish/fishtank.dm b/code/modules/fish/fishtank.dm
index eaa21b7dc702..36dc425b41ea 100644
--- a/code/modules/fish/fishtank.dm
+++ b/code/modules/fish/fishtank.dm
@@ -604,22 +604,22 @@
new /obj/item/stack/sheet/glass(get_turf(src), shard_count + 1) //Produce the appropriate number of glass sheets, in a single stack
qdel(src)
-/obj/machinery/fishtank/attackby__legacy__attackchain(obj/item/O, mob/user)
+/obj/machinery/fishtank/item_interaction(mob/living/user, obj/item/used, list/modifiers)
//Open reagent containers add and remove water
- if(O.is_drainable())
+ if(used.is_drainable())
//Containers with any reagents will get dumped in
- if(O.reagents.total_volume)
+ if(used.reagents.total_volume)
var/water_value = 0
- water_value += O.reagents.get_reagent_amount("water") //Water is full value
- water_value += O.reagents.get_reagent_amount("holywater") *1.1 //Holywater is (somehow) better. Who said religion had to make sense?
- water_value += O.reagents.get_reagent_amount("tonic") * 0.25 //Tonic water is 25% value
- water_value += O.reagents.get_reagent_amount("sodawater") * 0.50 //Sodawater is 50% value
- water_value += O.reagents.get_reagent_amount("fishwater") * 0.75 //Fishwater is 75% value, to account for the fish poo
- water_value += O.reagents.get_reagent_amount("ice") * 0.80 //Ice is 80% value
+ water_value += used.reagents.get_reagent_amount("water") //Water is full value
+ water_value += used.reagents.get_reagent_amount("holywater") *1.1 //Holywater is (somehow) better. Who said religion had to make sense?
+ water_value += used.reagents.get_reagent_amount("tonic") * 0.25 //Tonic water is 25% value
+ water_value += used.reagents.get_reagent_amount("sodawater") * 0.50 //Sodawater is 50% value
+ water_value += used.reagents.get_reagent_amount("fishwater") * 0.75 //Fishwater is 75% value, to account for the fish poo
+ water_value += used.reagents.get_reagent_amount("ice") * 0.80 //Ice is 80% value
var/message = ""
if(!water_value) //The container has no water value, clear everything in it
message = "The filtration process removes everything, leaving the water level unchanged."
- O.reagents.clear_reagents()
+ used.reagents.clear_reagents()
else
if(water_level == water_capacity)
to_chat(user, "[src] is already full!")
@@ -630,25 +630,27 @@
message += " You filled [src] to the brim!"
if((water_level + water_value) > water_capacity)
message += " You overfilled [src] and some water runs down the side, wasted."
- O.reagents.clear_reagents()
+ used.reagents.clear_reagents()
adjust_water_level(water_value)
- user.visible_message("[user.name] pours the contents of [O.name] into [src].", "[message]")
+ user.visible_message("[user.name] pours the contents of [used.name] into [src].", "[message]")
//Empty containers will scoop out water, filling the container as much as possible from the water_level
- else if(O.is_refillable())
+ else if(used.is_refillable())
if(!water_level)
to_chat(user, "[src] is empty!")
else
- if(water_level >= O.reagents.maximum_volume) //Enough to fill the container completely
- O.reagents.add_reagent("fishwater", O.reagents.maximum_volume)
- adjust_water_level(-O.reagents.maximum_volume)
- user.visible_message("[user.name] scoops out some water from [src].", "You completely fill [O.name] from [src].")
+ if(water_level >= used.reagents.maximum_volume) //Enough to fill the container completely
+ used.reagents.add_reagent("fishwater", used.reagents.maximum_volume)
+ adjust_water_level(-used.reagents.maximum_volume)
+ user.visible_message("[user.name] scoops out some water from [src].", "You completely fill [used.name] from [src].")
else //Fill the container as much as possible with the water_level
- O.reagents.add_reagent("fishwater", water_level)
+ used.reagents.add_reagent("fishwater", water_level)
adjust_water_level(-water_level)
- user.visible_message("[user.name] scoops out some water from [src].", "You fill [O.name] with the last of the water in [src].")
+ user.visible_message("[user.name] scoops out some water from [src].", "You fill [used.name] with the last of the water in [src].")
+
+ return ITEM_INTERACT_COMPLETE
//Fish eggs
- else if(istype(O, /obj/item/fish_eggs))
- var/obj/item/fish_eggs/egg = O
+ else if(istype(used, /obj/item/fish_eggs))
+ var/obj/item/fish_eggs/egg = used
//Don't add eggs if there is no water (they kinda need that to live)
if(!water_level)
to_chat(user, "[src] has no water; [egg.name] won't hatch without water!")
@@ -659,8 +661,10 @@
else
add_fish(egg.fish_type)
qdel(egg)
+
+ return ITEM_INTERACT_COMPLETE
//Fish food
- else if(istype(O, /obj/item/fishfood))
+ else if(istype(used, /obj/item/fishfood))
//Only add food if there is water and it isn't already full of food
if(water_level)
if(food_level < 10)
@@ -673,8 +677,10 @@
to_chat(user, "[src] already has plenty of food in it. You decide to not add more.")
else
to_chat(user, "[src] doesn't have any water in it. You should fill it with water first.")
+
+ return ITEM_INTERACT_COMPLETE
//Fish egg scoop
- else if(istype(O, /obj/item/egg_scoop))
+ else if(istype(used, /obj/item/egg_scoop))
if(egg_count)
// Is the user holding a fish bag?
var/obj/item/storage/bag/fish_bag
@@ -686,18 +692,22 @@
harvest_eggs(user, fish_bag)
else
user.visible_message("[user.name] fails to harvest any fish eggs from [src].", "There are no fish eggs in [src] to scoop out.")
+
+ return ITEM_INTERACT_COMPLETE
//Fish net
- else if(istype(O, /obj/item/fish_net))
+ else if(istype(used, /obj/item/fish_net))
harvest_fish(user)
+ return ITEM_INTERACT_COMPLETE
//Tank brush
- else if(istype(O, /obj/item/tank_brush))
+ else if(istype(used, /obj/item/tank_brush))
if(filth_level == 0)
to_chat(user, "[src] is already spotless!")
else
adjust_filth_level(-filth_level)
user.visible_message("[user.name] scrubs the inside of [src], cleaning the filth.", "You scrub the inside of [src], cleaning the filth.")
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/fishtank/wrench_act(mob/user, obj/item/I) //Wrenches can deconstruct empty tanks, but not tanks with any water. Kills any fish left inside and destroys any unharvested eggs in the process
. = TRUE
diff --git a/code/modules/food_and_drinks/drinks/bottler/bottler.dm b/code/modules/food_and_drinks/drinks/bottler/bottler.dm
index 998a0eba2390..18b702a2a681 100644
--- a/code/modules/food_and_drinks/drinks/bottler/bottler.dm
+++ b/code/modules/food_and_drinks/drinks/bottler/bottler.dm
@@ -40,49 +40,49 @@
else
qdel(recipe)
-/obj/machinery/bottler/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(!user.canUnEquip(O, 0))
- to_chat(user, "[O] is stuck to your hand, you can't seem to put it down!")
- return 0
- if(is_type_in_list(O,acceptable_items))
- if(istype(O, /obj/item/food))
- var/obj/item/food/S = O
+/obj/machinery/bottler/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(!user.canUnEquip(used, 0))
+ to_chat(user, "[used] is stuck to your hand, you can't seem to put it down!")
+ return ITEM_INTERACT_COMPLETE
+ if(is_type_in_list(used,acceptable_items))
+ if(istype(used, /obj/item/food))
+ var/obj/item/food/S = used
user.drop_item_to_ground(S)
if(S.reagents && !S.reagents.total_volume) //This prevents us from using empty foods, should one occur due to some sort of error
to_chat(user, "[S] is gone, oh no!")
qdel(S) //Delete the food object because it is useless even as food due to the lack of reagents
else
insert_item(S, user)
- return 1
- else if(istype(O, /obj/item/reagent_containers/drinks/cans))
- var/obj/item/reagent_containers/drinks/cans/C = O
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/reagent_containers/drinks/cans))
+ var/obj/item/reagent_containers/drinks/cans/C = used
if(C.reagents)
if(C.can_opened && C.reagents.total_volume) //This prevents us from using opened cans that still have something in them
to_chat(user, "Only unopened cans and bottles can be processed to ensure product integrity.")
- return 0
+ return ITEM_INTERACT_COMPLETE
user.drop_item_to_ground(C)
if(!C.reagents.total_volume) //Empty cans get recycled, even if they have somehow remained unopened due to some sort of error
recycle_container(C)
else //Full cans that are unopened get inserted for processing as ingredients
insert_item(C, user)
- return 1
+ return ITEM_INTERACT_COMPLETE
else
- user.drop_item_to_ground(O)
- insert_item(O, user)
- return 1
- else if(istype(O, /obj/item/trash/can)) //Crushed cans (and bottles) are returnable still
- var/obj/item/trash/can/C = O
+ user.drop_item_to_ground(used)
+ insert_item(used, user)
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/trash/can)) //Crushed cans (and bottles) are returnable still
+ var/obj/item/trash/can/C = used
user.drop_item_to_ground(C)
recycle_container(C)
- return 1
- else if(istype(O, /obj/item/stack/sheet)) //Sheets of materials can replenish the machine's supply of drink containers (when people inevitably don't return them)
- var/obj/item/stack/sheet/S = O
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/stack/sheet)) //Sheets of materials can replenish the machine's supply of drink containers (when people inevitably don't return them)
+ var/obj/item/stack/sheet/S = used
user.drop_item_to_ground(S)
process_sheets(S)
- return 1
+ return ITEM_INTERACT_COMPLETE
else //If it doesn't qualify in the above checks, we don't want it. Inform the person so they (ideally) stop trying to put the nuke disc in.
to_chat(user, "You aren't sure this is able to be processed by the machine.")
- return 0
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/bottler/wrench_act(mob/user, obj/item/I)
. = TRUE
diff --git a/code/modules/food_and_drinks/kitchen_machinery/cooker.dm b/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
index 17d86d656afd..5b4988bbcfb7 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
@@ -179,29 +179,30 @@
var/obj/item/food/type = new(get_turf(src))
return type
-/obj/machinery/cooker/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/cooker/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(upgradeable)
//Not all cooker types currently support build/upgrade stuff, so not all of it will work well with this
//Until we decide whether or not we want to bring back the cereal maker or old grill/oven in some form, this initial check will have to suffice
- if(istype(I, /obj/item/storage/part_replacer))
- exchange_parts(user, I)
- return
+ if(istype(used, /obj/item/storage/part_replacer))
+ exchange_parts(user, used)
+ return ITEM_INTERACT_COMPLETE
if(stat & (NOPOWER|BROKEN))
- return
+ return ITEM_INTERACT_COMPLETE
if(panel_open)
to_chat(user, "Close the panel first!")
- return
- if(istype(I, /obj/item/grab))
- return special_attack_grab(I, user)
- if(!checkValid(I, user))
- return
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/grab))
+ if(special_attack_grab(used, user))
+ return ITEM_INTERACT_COMPLETE
+ if(!checkValid(used, user))
+ return ITEM_INTERACT_COMPLETE
if(!burns)
- if(istype(I, /obj/item/food))
- if(checkCooked(I))
+ if(istype(used, /obj/item/food))
+ if(checkCooked(used))
to_chat(user, "That is already [thiscooktype], it would do nothing!")
- return
- putIn(I, user)
- for(var/mob/living/L in I.contents) //Emagged cookers - Any mob put in will not survive the trip
+ return ITEM_INTERACT_COMPLETE
+ putIn(used, user)
+ for(var/mob/living/L in used.contents) //Emagged cookers - Any mob put in will not survive the trip
if(L.stat != DEAD)
if(ispAI(L)) //Snowflake check because pAIs are weird
var/mob/living/silicon/pai/P = L
@@ -210,7 +211,8 @@
L.death()
break
- addtimer(CALLBACK(src, PROC_REF(finish_cook), I, user), cooktime)
+ addtimer(CALLBACK(src, PROC_REF(finish_cook), used, user), cooktime)
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/cooker/proc/finish_cook(obj/item/I, mob/user, params)
if(QDELETED(I)) //For situations where the item being cooked gets deleted mid-cook (primed grenades)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
index 1d00b3975626..f3d1fff923d0 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
@@ -43,15 +43,15 @@
var/obj/item/food/deepfryholder/type = new(get_turf(src))
return type
-/obj/machinery/cooker/deepfryer/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/drinks/ice))
- var/ice_amount = I.reagents.get_reagent_amount("ice")
+/obj/machinery/cooker/deepfryer/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/reagent_containers/glass) || istype(used, /obj/item/reagent_containers/drinks/ice))
+ var/ice_amount = used.reagents.get_reagent_amount("ice")
if(ice_amount)
- I.reagents.remove_all(I.reagents.total_volume)
+ used.reagents.remove_all(used.reagents.total_volume)
add_attack_logs(user, src, "poured [ice_amount]u ice into")
user.visible_message(
- "[user] pours [I] into [src], and it seems to fizz a bit.",
- "You pour [I] into [src], and it seems to fizz a bit.",
+ "[user] pours [used] into [src], and it seems to fizz a bit.",
+ "You pour [used] into [src], and it seems to fizz a bit.",
"You hear a splash, and a sizzle."
)
@@ -59,7 +59,7 @@
addtimer(CALLBACK(src, PROC_REF(boil_leadup), user), 4 SECONDS)
addtimer(CALLBACK(src, PROC_REF(make_foam), ice_amount), 5 SECONDS)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index a321b64f8406..35f1bd89078b 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -93,24 +93,24 @@
startgibbing(user)
-/obj/machinery/gibber/attackby__legacy__attackchain(obj/item/P, mob/user, params)
- if(istype(P, /obj/item/grab))
- var/obj/item/grab/G = P
+/obj/machinery/gibber/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/G = used
if(G.state < 2)
to_chat(user, "You need a better grip to do that!")
- return
+ return ITEM_INTERACT_COMPLETE
move_into_gibber(user,G.affecting)
qdel(G)
- return
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", P))
- return
+ if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", used))
+ return ITEM_INTERACT_COMPLETE
- if(default_unfasten_wrench(user, P, time = 4 SECONDS))
- return
+ if(default_unfasten_wrench(user, used, time = 4 SECONDS))
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_crowbar(user, P))
- return
+ if(default_deconstruction_crowbar(user, used))
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
index 672781e46dcc..d99d8389ce72 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
@@ -29,31 +29,32 @@
. = ..()
create_reagents(500)
-/obj/machinery/icemachine/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/reagent_containers/glass))
+/obj/machinery/icemachine/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/reagent_containers/glass))
if(beaker)
to_chat(user, "A container is already inside [src].")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- to_chat(user, "\The [I] is stuck to you!")
- return
- beaker = I
- I.forceMove(src)
- to_chat(user, "You add [I] to [src]")
+ to_chat(user, "\The [used] is stuck to you!")
+ return ITEM_INTERACT_COMPLETE
+ beaker = used
+ used.forceMove(src)
+ to_chat(user, "You add [used] to [src].")
updateUsrDialog()
- return
- if(istype(I, /obj/item/food/frozen/icecream))
- if(!I.reagents.has_reagent("sprinkles"))
- if(I.reagents.total_volume > 29)
- I.reagents.remove_any(1)
- I.reagents.add_reagent("sprinkles", 1)
- I.name += " with sprinkles"
- I.desc += ". This also has sprinkles."
+ return ITEM_INTERACT_COMPLETE
+
+ if(istype(used, /obj/item/food/frozen/icecream))
+ if(!used.reagents.has_reagent("sprinkles"))
+ if(used.reagents.total_volume > 29)
+ used.reagents.remove_any(1)
+ used.reagents.add_reagent("sprinkles", 1)
+ used.name += " with sprinkles"
+ used.desc += ". This also has sprinkles."
else
- to_chat(user, "This [I] already has sprinkles.")
- return
- return ..()
+ to_chat(user, "This [used] already has sprinkles.")
+ return ITEM_INTERACT_COMPLETE
+ return ..()
/obj/machinery/icemachine/Topic(href, href_list)
if(..()) return
diff --git a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
index eb860683b17f..4f6910352dc9 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
@@ -71,40 +71,40 @@
* Item Adding
********************/
-/obj/machinery/kitchen_machine/attackby__legacy__attackchain(obj/item/O, mob/user, params)
+/obj/machinery/kitchen_machine/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(operating)
- return
+ return ITEM_INTERACT_COMPLETE
if(dirty < MAX_DIRT)
- if(default_deconstruction_screwdriver(user, open_icon, off_icon, O))
- return
+ if(default_deconstruction_screwdriver(user, open_icon, off_icon, used))
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/storage/part_replacer))
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
- default_deconstruction_crowbar(user, O)
+ default_deconstruction_crowbar(user, used)
if(dirty == MAX_DIRT) // The machine is all dirty so can't be used!
- if(istype(O, /obj/item/reagent_containers/spray/cleaner) || istype(O, /obj/item/soap) || istype(O, /obj/item/reagent_containers/glass/rag)) // If they're trying to clean it then let them
+ if(istype(used, /obj/item/reagent_containers/spray/cleaner) || istype(used, /obj/item/soap) || istype(used, /obj/item/reagent_containers/glass/rag)) // If they're trying to clean it then let them
user.visible_message("[user] starts to clean [src].", "You start to clean [src].")
- if(do_after(user, 20 * O.toolspeed, target = src))
+ if(do_after(user, 20 * used.toolspeed, target = src))
user.visible_message("[user] has cleaned [src].", "You have cleaned [src].")
dirty = NO_DIRT
update_icon(UPDATE_ICON_STATE)
container_type = OPENCONTAINER
- return TRUE
+ return ITEM_INTERACT_COMPLETE
else //Otherwise bad luck!!
to_chat(user, "It's dirty!")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(is_type_in_list(O, GLOB.cooking_ingredients[recipe_type]) || istype(O, /obj/item/mixing_bowl))
+ if(is_type_in_list(used, GLOB.cooking_ingredients[recipe_type]) || istype(used, /obj/item/mixing_bowl))
if(length(contents) >= max_n_of_items)
to_chat(user, "This [src] is full of ingredients, you cannot put more.")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(istype(O,/obj/item/stack))
- var/obj/item/stack/S = O
+ if(istype(used,/obj/item/stack))
+ var/obj/item/stack/S = used
if(S.get_amount() > 1)
var/obj/item/stack/to_add = S.split(user, 1)
to_add.forceMove(src)
@@ -112,48 +112,49 @@
else
add_item(S, user)
else
- add_item(O, user)
- else if(is_type_in_list(O, list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/drinks, /obj/item/reagent_containers/condiment)))
- if(!O.reagents)
- return TRUE
+ add_item(used, user)
+ else if(is_type_in_list(used, list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/drinks, /obj/item/reagent_containers/condiment)))
+ if(!used.reagents)
+ return ITEM_INTERACT_COMPLETE
- for(var/datum/reagent/R in O.reagents.reagent_list)
+ for(var/datum/reagent/R in used.reagents.reagent_list)
if(!(R.id in GLOB.cooking_reagents[recipe_type]))
- to_chat(user, "Your [O.name] contains components unsuitable for cookery.")
- return TRUE
- else if(istype(O, /obj/item/storage))
- var/obj/item/storage/S = O
+ to_chat(user, "Your [used.name] contains components unsuitable for cookery.")
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/storage))
+ var/obj/item/storage/S = used
if(!S.allow_quick_empty)
- to_chat(user, "[O] is too awkward a shape to dump into [src].")
- return TRUE
+ to_chat(user, "[used] is too awkward a shape to dump into [src].")
+ return ITEM_INTERACT_COMPLETE
if(length(S.contents) + length(contents) >= max_n_of_items)
- to_chat(user, "You can't fit everything from [O] into [src].")
- return TRUE
+ to_chat(user, "You can't fit everything from [used] into [src].")
+ return ITEM_INTERACT_COMPLETE
if(length(S.contents) == 0)
- to_chat(user, "[O] is empty!")
- return TRUE
- for(var/obj/item/ingredient in O.contents)
+ to_chat(user, "[used] is empty!")
+ return ITEM_INTERACT_COMPLETE
+ for(var/obj/item/ingredient in used.contents)
if(!is_type_in_list(ingredient, GLOB.cooking_ingredients[recipe_type]) && !istype(ingredient, /obj/item/mixing_bowl))
- to_chat(user, "Your [O.name] contains contents unsuitable for cookery.")
- return TRUE
+ to_chat(user, "Your [used.name] contains contents unsuitable for cookery.")
+ return ITEM_INTERACT_COMPLETE
S.hide_from(user)
- user.visible_message("[user] dumps [O] into [src].", "You dump [O] into [src].")
- for(var/obj/item/ingredient in O.contents)
+ user.visible_message("[user] dumps [used] into [src].", "You dump [used] into [src].")
+ for(var/obj/item/ingredient in used.contents)
S.remove_from_storage(ingredient, src)
CHECK_TICK
SStgui.update_uis(src)
-
- else if(istype(O, /obj/item/grab))
- var/obj/item/grab/G = O
+ else if(istype(used, /obj/item/grab))
+ var/obj/item/grab/G = used
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "Slamming [G.affecting] into [src] might hurt them!")
- return
- return special_attack_grab(G, user)
-
+ return ITEM_INTERACT_COMPLETE
+ special_attack_grab(G, user)
+ return ITEM_INTERACT_COMPLETE
else
- to_chat(user, "You have no idea what you can cook with [O].")
- return TRUE
+ to_chat(user, "You have no idea what you can cook with [used].")
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/kitchen_machine/wrench_act(mob/living/user, obj/item/I)
if(operating)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
index a5079e4ffde8..6c8c512f58bb 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
@@ -54,21 +54,21 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
cube_production = cubes_made
required_grind = req_grind
-/obj/machinery/monkey_recycler/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", O))
- return
+/obj/machinery/monkey_recycler/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", used))
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/storage/part_replacer))
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
- if(default_unfasten_wrench(user, O, time = 4 SECONDS))
+ if(default_unfasten_wrench(user, used, time = 4 SECONDS))
power_change()
- return
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_crowbar(user, O))
- return
+ if(default_deconstruction_crowbar(user, used))
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/multitool))
+ if(istype(used, /obj/item/multitool))
if(!panel_open)
cycle_through++
switch(cycle_through)
@@ -87,14 +87,14 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
cycle_through = 0
to_chat(user, "You change the monkeycube type to [initial(cube_type.name)].")
else
- var/obj/item/multitool/M = O
+ var/obj/item/multitool/M = used
M.buffer = src
to_chat(user, "You log [src] in [M]'s buffer.")
- return
+ return ITEM_INTERACT_COMPLETE
if(stat != 0) //NOPOWER etc
- return
- if(istype(O, /obj/item/grab))
- var/obj/item/grab/G = O
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/G = used
var/grabbed = G.affecting
if(ishuman(grabbed))
var/mob/living/carbon/human/target = grabbed
@@ -117,7 +117,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
to_chat(user, "The machine only accepts monkeys!")
else
to_chat(user, "The machine only accepts monkeys!")
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/monkey_recycler/attack_hand(mob/user)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
index b77ab73200da..7926e2edf5a0 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
@@ -188,33 +188,33 @@
return P
return 0
-/obj/machinery/processor/attackby__legacy__attackchain(obj/item/O, mob/user, params)
+/obj/machinery/processor/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(processing)
to_chat(user, "\the [src] is already processing something!")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_screwdriver(user, "processor_open", "processor", O))
- return
+ if(default_deconstruction_screwdriver(user, "processor_open", "processor", used))
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/storage/part_replacer))
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
- if(default_unfasten_wrench(user, O, time = 4 SECONDS))
- return
+ if(default_unfasten_wrench(user, used, time = 4 SECONDS))
+ return ITEM_INTERACT_COMPLETE
- default_deconstruction_crowbar(user, O)
+ default_deconstruction_crowbar(user, used)
- var/obj/item/what = O
+ var/obj/item/what = used
- if(istype(O, /obj/item/grab))
- var/obj/item/grab/G = O
+ if(istype(used, /obj/item/grab))
+ var/obj/item/grab/G = used
what = G.affecting
var/datum/food_processor_process/P = select_recipe(what)
if(!P)
to_chat(user, "That probably won't blend.")
- return 1
+ return ITEM_INTERACT_COMPLETE
user.visible_message("\the [user] puts \the [what] into \the [src].", \
"You put \the [what] into \the [src].")
@@ -222,7 +222,7 @@
user.drop_item()
what.loc = src
- return
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/processor/attack_hand(mob/user)
if(stat & (NOPOWER|BROKEN)) //no power or broken
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 89e838074fe4..17cac16a67f2 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -177,27 +177,27 @@
return TRUE
return ..()
-/obj/machinery/smartfridge/attackby__legacy__attackchain(obj/item/O, mob/user)
- if(istype(O, /obj/item/storage/part_replacer))
+/obj/machinery/smartfridge/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/part_replacer))
. = ..()
SStgui.update_uis(src)
return
if(stat & (BROKEN|NOPOWER))
to_chat(user, "[src] is unpowered and useless.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(load(O, user))
+ if(load(used, user))
user.visible_message(
- "[user] has added [O] to [src].",
- "You add [O] to [src]."
+ "[user] has added [used] to [src].",
+ "You add [used] to [src]."
)
SStgui.update_uis(src)
update_icon(UPDATE_OVERLAYS)
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/storage/bag) || istype(O, /obj/item/storage/box))
- var/obj/item/storage/P = O
+ if(istype(used, /obj/item/storage/bag) || istype(used, /obj/item/storage/box))
+ var/obj/item/storage/P = used
var/items_loaded = 0
for(var/obj/G in P.contents)
if(load(G, user))
@@ -212,11 +212,13 @@
var/failed = length(P.contents)
if(failed)
to_chat(user, "[failed] item\s [failed == 1 ? "is" : "are"] refused.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(!istype(O, /obj/item/card/emag))
- to_chat(user, "\The [src] smartly refuses [O].")
- return TRUE
+ if(!istype(used, /obj/item/card/emag))
+ to_chat(user, "\The [src] smartly refuses [used].")
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/smartfridge/attack_ai(mob/user)
if(!silicon_controllable)
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index d37b07d3fbb3..a426e51ad241 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -102,42 +102,46 @@
/obj/machinery/biogenerator/crowbar_act(mob/living/user, obj/item/I)
return default_deconstruction_crowbar(user, I)
-/obj/machinery/biogenerator/attackby__legacy__attackchain(obj/item/O, mob/user, params)
+/obj/machinery/biogenerator/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ // TODO: This feels off, no where else do we have a blanket "print a
+ // message for any other kind of item interaction attempt" that's keyed to intent
+ // See if this can be made more sensible after everything's been migrated
+ // to the new attack chain
if(user.a_intent == INTENT_HARM)
return ..()
- if(istype(O, /obj/item/storage/part_replacer))
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
if(processing)
to_chat(user, "[src] is currently processing.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/reagent_containers/glass))
+ if(istype(used, /obj/item/reagent_containers/glass))
if(panel_open)
to_chat(user, "Close the maintenance panel first.")
- return
+ return ITEM_INTERACT_COMPLETE
if(container)
to_chat(user, "A container is already loaded into [src].")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- return
+ return ITEM_INTERACT_COMPLETE
- O.forceMove(src)
- container = O
+ used.forceMove(src)
+ container = used
to_chat(user, "You add the [container] to [src].")
update_icon(UPDATE_ICON_STATE)
SStgui.update_uis(src)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/storage/bag/plants))
+ else if(istype(used, /obj/item/storage/bag/plants))
if(length(stored_plants) >= max_storable_plants)
to_chat(user, "[src] can't hold any more plants!")
- return
+ return ITEM_INTERACT_COMPLETE
- var/obj/item/storage/bag/plants/PB = O
+ var/obj/item/storage/bag/plants/PB = used
for(var/obj/item/P in PB.contents)
// No need to filter here, because plant bags should have the same list of acceptable items we do.
if(length(stored_plants) >= max_storable_plants)
@@ -151,37 +155,38 @@
to_chat(user, "You fill [src] to its capacity.")
SStgui.update_uis(src)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(is_type_in_typecache(O, acceptable_items))
+ else if(is_type_in_typecache(used, acceptable_items))
if(length(stored_plants) >= max_storable_plants)
to_chat(user, "[src] can't hold any more plants!")
- return
- if(!user.drop_item_to_ground(O))
- return
+ return ITEM_INTERACT_COMPLETE
+ if(!user.drop_item_to_ground(used))
+ return ITEM_INTERACT_COMPLETE
- O.forceMove(src)
- stored_plants += O
- to_chat(user, "You put [O] in [src].")
+ used.forceMove(src)
+ stored_plants += used
+ to_chat(user, "You put [used] in [src].")
SStgui.update_uis(src)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/disk/design_disk))
- user.visible_message("[user] begins to load [O] in [src]...",
- "You begin to load a design from [O]...",
+ else if(istype(used, /obj/item/disk/design_disk))
+ user.visible_message("[user] begins to load [used] in [src]...",
+ "You begin to load a design from [used]...",
"You hear the chatter of a floppy drive.")
processing = TRUE
SStgui.update_uis(src)
- var/obj/item/disk/design_disk/D = O
+ var/obj/item/disk/design_disk/D = used
if(do_after(user, 1 SECONDS, target = src))
files.AddDesign2Known(D.blueprint)
processing = FALSE
update_ui_product_list(user)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You cannot put [src] in [name]!")
+ return ITEM_INTERACT_COMPLETE
/**
* Builds/Updates the `product_list` used by the UI.
diff --git a/code/modules/hydroponics/compost_bin.dm b/code/modules/hydroponics/compost_bin.dm
index 152ed33fa1c4..fb1c95d63a01 100644
--- a/code/modules/hydroponics/compost_bin.dm
+++ b/code/modules/hydroponics/compost_bin.dm
@@ -66,16 +66,20 @@
qdel(O)
// takes care of plant insertion and conversion to biomass, and start composting what was inserted
-/obj/machinery/compost_bin/attackby__legacy__attackchain(obj/item/O, mob/user, params)
+/obj/machinery/compost_bin/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ // TODO: This feels off, no where else do we have a blanket "print a
+ // message for any other kind of item interaction attempt" that's keyed to intent
+ // See if this can be made more sensible after everything's been migrated
+ // to the new attack chain
if(user.a_intent == INTENT_HARM)
return ..()
- if(istype(O, /obj/item/storage/bag/plants))
+ if(istype(used, /obj/item/storage/bag/plants))
if(biomass >= biomass_capacity && potassium >= potassium_capacity)
to_chat(user, "[src] can't hold any more biomass, and it's contents are saturated with potassium!")
- return
+ return ITEM_INTERACT_COMPLETE
- var/obj/item/storage/bag/plants/PB = O
+ var/obj/item/storage/bag/plants/PB = used
for(var/obj/item/food/grown/G in PB.contents)
// if the plant contains either potassium, plantmatter and nutriment and the compost bin has space for any of those.
if((G.reagents.get_reagent_amount("potassium") && potassium <= potassium_capacity) || ((G.reagents.get_reagent_amount("plantmatter") || G.reagents.get_reagent_amount("nutriment")) && biomass <= biomass_capacity))
@@ -97,30 +101,30 @@
SStgui.update_uis(src)
update_icon(UPDATE_ICON_STATE)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/food/grown))
+ if(istype(used, /obj/item/food/grown))
if(biomass >= biomass_capacity && potassium >= potassium_capacity)
to_chat(user, "[src] can't hold any more biomass, and its contents are saturated with potassium!")
- return
- if(!user.drop_item_to_ground(O))
- return
+ return ITEM_INTERACT_COMPLETE
+ if(!user.drop_item_to_ground(used))
+ return ITEM_INTERACT_COMPLETE
- O.forceMove(src)
- make_biomass(O)
- to_chat(user, "You put [O] in [src].")
+ used.forceMove(src)
+ make_biomass(used)
+ to_chat(user, "You put [used] in [src].")
SStgui.update_uis(src)
update_icon(UPDATE_ICON_STATE)
- return TRUE
- if(istype(O, /obj/item/reagent_containers))
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/reagent_containers))
var/proportion = 0
- var/obj/item/reagent_containers/B = O
+ var/obj/item/reagent_containers/B = used
if(B.reagents.total_volume <= 0)
to_chat(user, "[B] is empty!")
- return
+ return ITEM_INTERACT_COMPLETE
if(potassium >= potassium_capacity && potash >= potash_capacity)
to_chat(user, "The contents of [src] are saturated with potassium and it cannot hold more potash!")
- return
+ return ITEM_INTERACT_COMPLETE
// Won't pour in more than the amount of potassium that can be accepted, even if the beaker is not filled with pure potassium.
proportion = min(min(B.reagents.total_volume, B.amount_per_transfer_from_this), potassium_capacity - potassium) / B.reagents.total_volume
@@ -156,9 +160,10 @@
SStgui.update_uis(src)
update_icon(UPDATE_ICON_STATE)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You cannot put this in [src]!")
+ return ITEM_INTERACT_COMPLETE
//Compost compostable material if there is any
/obj/machinery/compost_bin/process()
diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm
index fbbb0238fda7..54fa10e4018e 100644
--- a/code/modules/hydroponics/gene_modder.dm
+++ b/code/modules/hydroponics/gene_modder.dm
@@ -130,25 +130,25 @@
if(panel_open)
. += "dnamod-open"
-/obj/machinery/plantgenes/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I))
+/obj/machinery/plantgenes/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", used))
update_icon(UPDATE_OVERLAYS)
- return
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_crowbar(user, I))
- return
+ if(default_deconstruction_crowbar(user, used))
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/unsorted_seeds))
- to_chat(user, "You need to sort [I] first!")
- return
+ if(istype(used, /obj/item/unsorted_seeds))
+ to_chat(user, "You need to sort [used] first!")
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/seeds))
- add_seed(I, user)
- return
+ if(istype(used, /obj/item/seeds))
+ add_seed(used, user)
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/disk/plantgene) || istype(I, /obj/item/storage/box))
- add_disk(I, user)
- return
+ if(istype(used, /obj/item/disk/plantgene) || istype(used, /obj/item/storage/box))
+ add_disk(used, user)
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/hydroponics/hydroponics_tray.dm b/code/modules/hydroponics/hydroponics_tray.dm
index 3174a1a4d625..63194d4b342c 100644
--- a/code/modules/hydroponics/hydroponics_tray.dm
+++ b/code/modules/hydroponics/hydroponics_tray.dm
@@ -123,9 +123,10 @@
QDEL_NULL(myseed)
return ..()
-/obj/machinery/hydroponics/constructable/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, "hydrotray3", "hydrotray3", I))
- return
+/obj/machinery/hydroponics/constructable/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_deconstruction_screwdriver(user, "hydrotray3", "hydrotray3", used))
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/hydroponics/constructable/crowbar_act(mob/user, obj/item/I)
@@ -770,25 +771,25 @@
to_chat(user, message.Join(""))
doping_chem = new_chem
-/obj/machinery/hydroponics/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- //Called when mob user "attacks" it with object O
- if(istype(O, /obj/item/reagent_containers)) // Syringe stuff (and other reagent containers now too)
- var/obj/item/reagent_containers/reagent_source = O
+/obj/machinery/hydroponics/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ //Called when mob user "attacks" it with object `used`
+ if(istype(used, /obj/item/reagent_containers)) // Syringe stuff (and other reagent containers now too)
+ var/obj/item/reagent_containers/reagent_source = used
var/target = myseed ? myseed.plantname : src
if(istype(reagent_source, /obj/item/reagent_containers/syringe))
var/obj/item/reagent_containers/syringe/syr = reagent_source
if(syr.mode != SYRINGE_INJECT)
to_chat(user, "You can't get any extract out of this plant.") //That. Gives me an idea...
- return TRUE
+ return ITEM_INTERACT_COMPLETE
if(!reagent_source.reagents.total_volume)
to_chat(user, "[reagent_source] is empty.")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
if(reagent_source.has_lid && !reagent_source.is_drainable()) //if theres a LID then cannot transfer reagents.
- to_chat(user, "You need to open [O] first!")
- return TRUE
+ to_chat(user, "You need to open [used] first!")
+ return ITEM_INTERACT_COMPLETE
var/visi_msg = ""
var/transfer_amount = reagent_source.amount_per_transfer_from_this
@@ -814,41 +815,44 @@
playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE)
add_compost(reagent_source, user, transfer_amount, visi_msg, irrigate)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- else if(isfood(O) || istype(O, /obj/item/grown))
+ else if(isfood(used) || istype(used, /obj/item/grown))
var/target = myseed ? myseed.plantname : src
- var/transfer = O.reagents.total_volume
- var/message = "[user] composts [O], spreading it through [target]"
- add_compost(O, user, transfer, message)
- return TRUE
+ var/transfer = used.reagents.total_volume
+ var/message = "[user] composts [used], spreading it through [target]"
+ add_compost(used, user, transfer, message)
+ return ITEM_INTERACT_COMPLETE
- else if(istype(O, /obj/item/unsorted_seeds))
- to_chat(user, "You need to sort [O] first!")
- return ..()
+ else if(istype(used, /obj/item/unsorted_seeds))
+ to_chat(user, "You need to sort [used] first!")
+ return ITEM_INTERACT_COMPLETE
- else if(istype(O, /obj/item/seeds) && !istype(O, /obj/item/seeds/sample))
+ else if(istype(used, /obj/item/seeds) && !istype(used, /obj/item/seeds/sample))
if(!myseed)
- if(istype(O, /obj/item/seeds/kudzu))
+ if(istype(used, /obj/item/seeds/kudzu))
investigate_log("had Kudzu planted in it by [key_name(user)] at ([x],[y],[z])","kudzu")
- user.unequip(O)
- to_chat(user, "You plant [O].")
+ user.unequip(used)
+ to_chat(user, "You plant [used].")
dead = FALSE
- myseed = O
+ myseed = used
age = 1
plant_health = myseed.endurance
plant_hud_set_health()
plant_hud_set_status()
lastcycle = world.time
- O.forceMove(src)
+ used.forceMove(src)
update_state()
else
to_chat(user, "[src] already has seeds in it!")
- else if(istype(O, /obj/item/plant_analyzer))
+ return ITEM_INTERACT_COMPLETE
+
+ else if(istype(used, /obj/item/plant_analyzer))
send_plant_details(user)
+ return ITEM_INTERACT_COMPLETE
- else if(istype(O, /obj/item/cultivator))
+ else if(istype(used, /obj/item/cultivator))
if(weedlevel > 0)
user.visible_message("[user] uproots the weeds.", "You remove the weeds from [src].")
adjustWeeds(-10)
@@ -856,23 +860,25 @@
else
to_chat(user, "This plot is completely devoid of weeds! It doesn't need uprooting.")
- else if(istype(O, /obj/item/storage/bag/plants))
+ else if(istype(used, /obj/item/storage/bag/plants))
if(!harvest)
attack_hand(user)
- return
+ return ITEM_INTERACT_COMPLETE
- myseed.harvest(user, O)
+ myseed.harvest(user, used)
- else if(istype(O, /obj/item/shovel/spade))
+ return ITEM_INTERACT_COMPLETE
+
+ else if(istype(used, /obj/item/shovel/spade))
if(!myseed && !weedlevel)
to_chat(user, "[src] doesn't have any plants or weeds!")
- return
+ return ITEM_INTERACT_COMPLETE
user.visible_message("[user] starts digging out [src]'s plants...", "You start digging out [src]'s plants...")
- playsound(src, O.usesound, 50, 1)
- if(!do_after(user, 25 * O.toolspeed, target = src) || (!myseed && !weedlevel))
- return
+ playsound(src, used.usesound, 50, 1)
+ if(!do_after(user, 25 * used.toolspeed, target = src) || (!myseed && !weedlevel))
+ return ITEM_INTERACT_COMPLETE
user.visible_message("[user] digs out the plants in [src]!", "You dig out all of [src]'s plants!")
- playsound(src, O.usesound, 50, 1)
+ playsound(src, used.usesound, 50, 1)
if(myseed) //Could be that they're just using it as a de-weeder
age = 0
plant_health = 0
@@ -886,8 +892,10 @@
plant_hud_set_status()
adjustWeeds(-10) //Has a side effect of cleaning up those nasty weeds
update_state()
- else if(is_pen(O) && myseed)
+ return ITEM_INTERACT_COMPLETE
+ else if(is_pen(used) && myseed)
myseed.variant_prompt(user, src)
+ return ITEM_INTERACT_COMPLETE
else
return ..()
@@ -1028,12 +1036,13 @@
/obj/machinery/hydroponics/soil/update_icon_lights()
return // Has no lights
-/obj/machinery/hydroponics/soil/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/shovel) && !istype(O, /obj/item/shovel/spade)) //Doesn't include spades because of uprooting plants
+/obj/machinery/hydroponics/soil/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/shovel) && !istype(used, /obj/item/shovel/spade)) //Doesn't include spades because of uprooting plants
to_chat(user, "You clear up [src]!")
qdel(src)
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/hydroponics/proc/add_compost(obj/item/reagent_source, mob/user, transfer_amount, visi_msg, irrigate = FALSE)
var/list/trays = list(src)//makes the list just this in cases of syringes and compost etc
diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm
index 1f9d9feb17e3..e3a76b98994c 100644
--- a/code/modules/hydroponics/seed_extractor.dm
+++ b/code/modules/hydroponics/seed_extractor.dm
@@ -74,23 +74,23 @@
for(var/obj/item/stock_parts/manipulator/M in component_parts)
seed_multiplier = M.rating
-/obj/machinery/seed_extractor/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O))
- return
+/obj/machinery/seed_extractor/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", used))
+ return ITEM_INTERACT_COMPLETE
- if(default_unfasten_wrench(user, O, time = 4 SECONDS))
- return
+ if(default_unfasten_wrench(user, used, time = 4 SECONDS))
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_crowbar(user, O))
- return
+ if(default_deconstruction_crowbar(user, used))
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/storage/part_replacer))
+ if(istype(used, /obj/item/storage/part_replacer))
. = ..()
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/storage/bag/plants))
- var/obj/item/storage/P = O
+ if(istype(used, /obj/item/storage/bag/plants))
+ var/obj/item/storage/P = used
var/loaded = 0
for(var/obj/item/seeds/G in P)
if(length(contents) >= max_seeds)
@@ -99,7 +99,7 @@
add_seed(G, user)
if(loaded)
- to_chat(user, "You transfer [loaded] seeds from [O] into [src].")
+ to_chat(user, "You transfer [loaded] seeds from [used] into [src].")
SStgui.update_uis(src)
else
var/seedable = 0
@@ -108,33 +108,34 @@
for(var/obj/item/grown/ignored in P)
seedable++
if(!seedable)
- to_chat(user, "There are no seeds or plants in [O].")
- return
+ to_chat(user, "There are no seeds or plants in [used].")
+ return ITEM_INTERACT_COMPLETE
- to_chat(user, "You dump the plants in [O] into [src].")
- if(!O.use_tool(src, user, min(5, seedable/2) SECONDS))
- return
+ to_chat(user, "You dump the plants in [used] into [src].")
+ if(!used.use_tool(src, user, min(5, seedable/2) SECONDS))
+ return ITEM_INTERACT_COMPLETE
for(var/thing in P)
seedify(thing,-1, src, user)
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/unsorted_seeds))
- to_chat(user, "You need to sort [O] first!")
- return ..()
+ if(istype(used, /obj/item/unsorted_seeds))
+ to_chat(user, "You need to sort [used] first!")
+ return ITEM_INTERACT_COMPLETE
- if(istype(O, /obj/item/seeds))
- add_seed(O, user)
- to_chat(user, "You add [O] to [name].")
+ if(istype(used, /obj/item/seeds))
+ add_seed(used, user)
+ to_chat(user, "You add [used] to [name].")
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
- if(seedify(O,-1, src, user))
+ if(seedify(used,-1, src, user))
to_chat(user, "You extract some seeds.")
- return
+ return ITEM_INTERACT_COMPLETE
if(user.a_intent != INTENT_HARM)
- to_chat(user, "You can't extract any seeds from \the [O.name]!")
+ to_chat(user, "You can't extract any seeds from \the [used.name]!")
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/library/library_computer.dm b/code/modules/library/library_computer.dm
index 56cbb2c9539b..54c6f3a900ce 100644
--- a/code/modules/library/library_computer.dm
+++ b/code/modules/library/library_computer.dm
@@ -65,22 +65,22 @@
/obj/machinery/computer/library/attack_ghost(mob/user)
ui_interact(user)
-/obj/machinery/computer/library/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/book))
- select_book(O)
- return
- if(istype(O, /obj/item/barcodescanner))
- var/obj/item/barcodescanner/B = O
+/obj/machinery/computer/library/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/book))
+ select_book(used)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/barcodescanner))
+ var/obj/item/barcodescanner/B = used
if(!B.connect(src))
playsound(src, 'sound/machines/synth_no.ogg', 15, TRUE)
to_chat(user, "ERROR: No Connection Established!")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "Barcode Scanner Successfully Connected to Computer.")
audible_message("[src] lets out a low, short blip.", hearing_distance = 2)
playsound(B, 'sound/machines/terminal_select.ogg', 10, TRUE)
- return
- if(istype(O, /obj/item/card/id))
- var/obj/item/card/id/ID = O //at some point, this should be moved over to its own proc (select_patron()???)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/card/id))
+ var/obj/item/card/id/ID = used //at some point, this should be moved over to its own proc (select_patron()???)
if(ID.registered_name)
user_data.patron_name = ID.registered_name
else
@@ -88,17 +88,17 @@
user_data.patron_account = null //account number should reset every scan so we don't accidently have an account number but no name
playsound(src, 'sound/machines/synth_no.ogg', 15, TRUE)
to_chat(user, "ERROR: No name detected!")
- return //no point in continuing if the ID card has no associated name!
+ return ITEM_INTERACT_COMPLETE //no point in continuing if the ID card has no associated name!
playsound(src, 'sound/items/scannerbeep.ogg', 15, TRUE)
if(ID.associated_account_number)
user_data.patron_account = ID.associated_account_number
else
user_data.patron_account = null
to_chat(user, "[src]'s screen flashes: 'WARNING! Patron without associated account number Selected'")
- return
+ return ITEM_INTERACT_COMPLETE
- if(default_unfasten_wrench(user, O, time = 60))
- return
+ if(default_unfasten_wrench(user, used, time = 60))
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/library/library_equipment.dm b/code/modules/library/library_equipment.dm
index 33f2180b308e..4453dcabc498 100644
--- a/code/modules/library/library_equipment.dm
+++ b/code/modules/library/library_equipment.dm
@@ -199,15 +199,18 @@
ui_interact(user)
-/obj/machinery/bookbinder/attackby__legacy__attackchain(obj/item/I, mob/user)
- if(istype(I, /obj/item/paper))
- select_paper(I)
- if(istype(I, /obj/item/paper_bundle))
- select_paper_stack(I)
- if(istype(I, /obj/item/book))
- select_book(I)
- if(default_unfasten_wrench(user, I, time = 60))
- return
+/obj/machinery/bookbinder/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/paper))
+ select_paper(used)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/paper_bundle))
+ select_paper_stack(used)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/book))
+ select_book(used)
+ return ITEM_INTERACT_COMPLETE
+ if(default_unfasten_wrench(user, used, time = 60))
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/mining/laborcamp/laborshuttle.dm b/code/modules/mining/laborcamp/laborshuttle.dm
index afe662bb5a7f..4e64315478b8 100644
--- a/code/modules/mining/laborcamp/laborshuttle.dm
+++ b/code/modules/mining/laborcamp/laborshuttle.dm
@@ -46,20 +46,21 @@
QDEL_NULL(announcer)
return ..()
-/obj/machinery/mineral/labor_prisoner_shuttle_console/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/card/id/prisoner))
+/obj/machinery/mineral/labor_prisoner_shuttle_console/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/card/id/prisoner))
if(inserted_id_uid)
to_chat(user, "There's an ID inserted already.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(!user.drop_item_to_ground(I))
- return
+ if(!user.drop_item_to_ground(used))
+ return ITEM_INTERACT_COMPLETE
- I.forceMove(src)
- inserted_id_uid = I.UID()
- to_chat(user, "You insert [I].")
+ used.forceMove(src)
+ inserted_id_uid = used.UID()
+ to_chat(user, "You insert [used].")
SStgui.update_uis(src)
- return
+
+ return ITEM_INTERACT_COMPLETE
return ..()
@@ -172,18 +173,19 @@
return
user.examinate(src)
-/obj/machinery/mineral/labor_points_checker/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/card/id/prisoner))
- var/obj/item/card/id/prisoner/prisoner_id = I
+/obj/machinery/mineral/labor_points_checker/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/card/id/prisoner))
+ var/obj/item/card/id/prisoner/prisoner_id = used
if(!prisoner_id.goal)
to_chat(user, "Error: No point quota assigned by security, exiting.")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "ID: [prisoner_id.registered_name]")
to_chat(user, "Points Collected:[prisoner_id.mining_points]")
to_chat(user, "Point Quota: [prisoner_id.goal]")
to_chat(user, "Collect points by bringing ore to the labor camp ore redemption machine. Reach your quota to earn your release.")
- return
- if(istype(I, /obj/item/card/id))
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/card/id))
to_chat(user, "Error: Invalid ID")
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm
index 740a502eab19..a67f1adf036e 100644
--- a/code/modules/mining/lavaland/loot/colossus_loot.dm
+++ b/code/modules/mining/lavaland/loot/colossus_loot.dm
@@ -49,8 +49,8 @@
..()
ActivationReaction(user,"touch")
-/obj/machinery/anomalous_crystal/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- ActivationReaction(user,"weapon")
+/obj/machinery/anomalous_crystal/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ ActivationReaction(user, "weapon")
return ..()
/obj/machinery/anomalous_crystal/bullet_act(obj/item/projectile/P, def_zone)
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index dbb770a72c7d..60eeca60d177 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -180,18 +180,18 @@
message_sent = TRUE
// Interactions
-/obj/machinery/mineral/ore_redemption/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/storage/part_replacer))
+/obj/machinery/mineral/ore_redemption/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
if(!has_power())
return ..()
- if(istype(I, /obj/item/card/id))
- var/obj/item/card/id/ID = I
+ if(istype(used, /obj/item/card/id))
+ var/obj/item/card/id/ID = used
if(!points)
to_chat(usr, "There are no points to claim.");
- return
+ return ITEM_INTERACT_COMPLETE
if(anyone_claim || (req_access_claim in ID.access))
ID.mining_points += points
ID.total_mining_points += points
@@ -201,25 +201,25 @@
else
to_chat(usr, "Required access not found.")
add_fingerprint(usr)
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/disk/design_disk))
+ if(istype(used, /obj/item/disk/design_disk))
if(!user.drop_item())
- return
- I.forceMove(src)
- inserted_disk = I
+ return ITEM_INTERACT_COMPLETE
+ used.forceMove(src)
+ inserted_disk = used
SStgui.update_uis(src)
interact(user)
user.visible_message(
- "[user] inserts [I] into [src].",
- "You insert [I] into [src]."
+ "[user] inserts [used] into [src].",
+ "You insert [used] into [src]."
)
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/gripper))
+ if(istype(used, /obj/item/gripper))
if(!try_refill_storage(user))
to_chat(user, "You fail to retrieve any sheets from [src].")
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index f068ace4aa94..bc02fe6212b9 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -220,25 +220,25 @@
return FALSE
add_fingerprint()
-/obj/machinery/mineral/equipment_vendor/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/mineral/equipment_vendor/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(panel_open)
- return TRUE
- if(istype(I, /obj/item/mining_voucher))
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/mining_voucher))
if(!has_power())
- return
- redeem_voucher(I, user)
- return
- if(istype(I, /obj/item/card/id))
+ return ITEM_INTERACT_COMPLETE
+ redeem_voucher(used, user)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/card/id))
if(!has_power())
- return
+ return ITEM_INTERACT_COMPLETE
var/obj/item/card/id/C = user.get_active_hand()
if(istype(C) && !istype(inserted_id))
if(!user.drop_item())
- return
+ return ITEM_INTERACT_COMPLETE
C.forceMove(src)
inserted_id = C
ui_interact(user)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/mineral/equipment_vendor/crowbar_act(mob/living/user, obj/item/I)
@@ -446,30 +446,30 @@
EQUIPMENT("Point Transfer Card", /obj/item/card/mining_point_card, 500),
)
-/obj/machinery/mineral/equipment_vendor/explorer/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, "explorer-open", "explorer", I))
- return
+/obj/machinery/mineral/equipment_vendor/explorer/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_deconstruction_screwdriver(user, "explorer-open", "explorer", used))
+ return ITEM_INTERACT_COMPLETE
if(panel_open)
- if(istype(I, /obj/item/crowbar))
+ if(istype(used, /obj/item/crowbar))
remove_id()
- default_deconstruction_crowbar(user, I)
- return TRUE
- if(istype(I, /obj/item/mining_voucher))
+ default_deconstruction_crowbar(user, used)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/mining_voucher))
if(!has_power())
- return
- redeem_voucher(I, user)
- return
- if(istype(I, /obj/item/card/id))
+ return ITEM_INTERACT_COMPLETE
+ redeem_voucher(used, user)
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/card/id))
if(!has_power())
- return
+ return ITEM_INTERACT_COMPLETE
var/obj/item/card/id/C = user.get_active_hand()
if(istype(C) && !istype(inserted_id))
if(!user.drop_item())
- return
+ return ITEM_INTERACT_COMPLETE
C.forceMove(src)
inserted_id = C
ui_interact(user)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
/**********************Mining Equipment Datum**************************/
diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm
index 099d937ccd46..b9953b6d6391 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -122,18 +122,19 @@
if("ejectBag")
eject_bag(usr)
-/obj/machinery/mineral/mint/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/storage/bag/money))
+/obj/machinery/mineral/mint/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/bag/money))
if(money_bag)
to_chat(user, "There is already a [money_bag.name] inside!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- return
- to_chat(user, "You put a [I.name] into a [src].")
- I.forceMove(src)
- money_bag = I
+ return ITEM_INTERACT_COMPLETE
+ to_chat(user, "You put a [used.name] into a [src].")
+ used.forceMove(src)
+ money_bag = used
SStgui.update_uis(src)
- return
+
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 0062176085c7..8901c0271830 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -114,8 +114,10 @@
usr.show_message(t, EMOTE_VISIBLE)
/mob/proc/show_message(msg, type, alt, alt_type, chat_message_type) // Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
+#ifndef GAME_TESTS
if(!client)
return
+#endif
if(type)
if(type & EMOTE_VISIBLE && !has_vision(information_only = TRUE)) // Vision related
diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm
index c2aa0c5330e6..de9b34236f53 100644
--- a/code/modules/paperwork/faxmachine.dm
+++ b/code/modules/paperwork/faxmachine.dm
@@ -90,15 +90,17 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
/obj/machinery/photocopier/faxmachine/attack_ghost(mob/user)
ui_interact(user)
-/obj/machinery/photocopier/faxmachine/attackby__legacy__attackchain(obj/item/item, mob/user, params)
- if(istype(item,/obj/item/card/id) && !scan)
- scan(item)
- else if(istype(item, /obj/item/paper) || istype(item, /obj/item/photo) || istype(item, /obj/item/paper_bundle))
- ..()
+/obj/machinery/photocopier/faxmachine/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/card/id) && !scan)
+ scan(used)
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/paper) || istype(used, /obj/item/photo) || istype(used, /obj/item/paper_bundle))
+ . = ..()
SStgui.update_uis(src)
- else if(istype(item, /obj/item/folder))
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/folder))
to_chat(user, "The [src] can't accept folders!")
- return //early return so the parent proc doesn't suck up and items that a photocopier would take
+ return ITEM_INTERACT_COMPLETE //early return so the parent proc doesn't suck up and items that a photocopier would take
else
return ..()
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 0ddea1a79e25..a1196b3a6768 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -474,35 +474,41 @@
use_power(active_power_consumption)
COOLDOWN_START(src, copying_cooldown, PHOTOCOPIER_DELAY)
-/obj/machinery/photocopier/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/paper) || istype(O, /obj/item/photo) || istype(O, /obj/item/paper_bundle))
+/obj/machinery/photocopier/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/paper) || istype(used, /obj/item/photo) || istype(used, /obj/item/paper_bundle))
if(!copyitem)
user.drop_item()
- copyitem = O
- O.forceMove(src)
- to_chat(user, "You insert \the [O] into \the [src].")
+ copyitem = used
+ used.forceMove(src)
+ to_chat(user, "You insert \the [used] into \the [src].")
flick(insert_anim, src)
else
to_chat(user, "There is already something in \the [src].")
- else if(istype(O, /obj/item/toner))
+
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/toner))
if(toner <= 10) //allow replacing when low toner is affecting the print darkness
user.drop_item()
to_chat(user, "You insert the toner cartridge into \the [src].")
- var/obj/item/toner/T = O
+ var/obj/item/toner/T = used
toner += T.toner_amount
- qdel(O)
+ qdel(used)
else
to_chat(user, "This cartridge is not yet ready for replacement! Use up the rest of the toner.")
- else if(istype(O, /obj/item/folder))
+
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/folder))
if(!folder) //allow replacing when low toner is affecting the print darkness
user.drop_item()
- to_chat(user, "You slide the [O] into \the [src].")
- folder = O
- O.forceMove(src)
+ to_chat(user, "You slide the [used] into \the [src].")
+ folder = used
+ used.forceMove(src)
else
to_chat(user, "This cartridge is not yet ready for replacement! Use up the rest of the toner.")
- else if(istype(O, /obj/item/grab)) //For ass-copying.
- var/obj/item/grab/G = O
+
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/grab)) //For ass-copying.
+ var/obj/item/grab/G = used
if(ismob(G.affecting) && G.affecting != copymob)
var/mob/GM = G.affecting
visible_message("[usr] drags [GM.name] onto the photocopier!")
@@ -511,6 +517,8 @@
if(copyitem)
copyitem.forceMove(get_turf(src))
copyitem = null
+
+ return ITEM_INTERACT_COMPLETE
else
return ..()
diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm
index b6b3fd5cf404..7c96f931faea 100644
--- a/code/modules/paperwork/ticketmachine.dm
+++ b/code/modules/paperwork/ticketmachine.dm
@@ -118,16 +118,16 @@
maptext_x = 8
maptext = "[ticket_number]"
-/obj/machinery/ticket_machine/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/hand_labeler_refill))
+/obj/machinery/ticket_machine/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/hand_labeler_refill))
if(!(ticket_number >= max_number))
- to_chat(user, "[src] refuses [I]! There [max_number-ticket_number==1 ? "is" : "are"] still [max_number-ticket_number] ticket\s left!")
- return
+ to_chat(user, "[src] refuses [used]! There [max_number-ticket_number==1 ? "is" : "are"] still [max_number-ticket_number] ticket\s left!")
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You start to refill [src]'s ticket holder (doing this will reset its ticket count!).")
if(do_after(user, 30, target = src))
- to_chat(user, "You insert [I] into [src] as it whirs nondescriptly.")
+ to_chat(user, "You insert [used] into [src] as it whirs nondescriptly.")
user.drop_item()
- qdel(I)
+ qdel(used)
ticket_number = 0
current_number = 0
for(var/obj/item/ticket_machine_ticket/ticket in tickets)
@@ -136,16 +136,18 @@
tickets.Cut()
max_number = initial(max_number)
update_icon()
- return
- else if(istype(I, /obj/item/card/id))
- var/obj/item/card/id/heldID = I
+
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/card/id))
+ var/obj/item/card/id/heldID = used
if(ACCESS_HOP in heldID.access)
dispense_enabled = !dispense_enabled
to_chat(user, "You [dispense_enabled ? "enable" : "disable"] [src], it will [dispense_enabled ? "now" : "no longer"] dispense tickets!")
handle_maptext()
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You do not have the required access to [dispense_enabled ? "disable" : "enable"] the ticket machine.")
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/ticket_machine/proc/reset_cooldown()
diff --git a/code/modules/power/apc/apc.dm b/code/modules/power/apc/apc.dm
index ffb063c52d4e..1930d516bf74 100644
--- a/code/modules/power/apc/apc.dm
+++ b/code/modules/power/apc/apc.dm
@@ -237,24 +237,23 @@
if(isAntag(user))
. += "An APC can be emagged to unlock it, this will keep it in it's refresh state, making very obvious something is wrong."
-//attack with an item - open/close cover, insert cell, or (un)lock interface
-/obj/machinery/power/apc/attackby__legacy__attackchain(obj/item/W, mob/living/user, params)
-
+/obj/machinery/power/apc/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(issilicon(user) && get_dist(src, user) > 1)
- return attack_hand(user)
+ attack_hand(user)
+ return ITEM_INTERACT_COMPLETE
- else if(istype(W, /obj/item/stock_parts/cell) && opened) // trying to put a cell inside
+ else if(istype(used, /obj/item/stock_parts/cell) && opened) // trying to put a cell inside
if(cell)
to_chat(user, "There is a power cell already installed!")
- return
+ return ITEM_INTERACT_COMPLETE
else
if(stat & MAINT)
to_chat(user, "There is no connector for your power cell!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- return
- W.forceMove(src)
- cell = W
+ return ITEM_INTERACT_COMPLETE
+ used.forceMove(src)
+ cell = used
for(var/mob/living/simple_animal/demon/pulse_demon/demon in cell)
demon.forceMove(src)
@@ -270,90 +269,96 @@
chargecount = 0
update_icon()
- else if(W.GetID()) // trying to unlock the interface with an ID card
+ return ITEM_INTERACT_COMPLETE
+ else if(used.GetID()) // trying to unlock the interface with an ID card
togglelock(user)
+ return ITEM_INTERACT_COMPLETE
- else if(istype(W, /obj/item/stack/cable_coil) && opened)
+ else if(istype(used, /obj/item/stack/cable_coil) && opened)
var/turf/host_turf = get_turf(src)
if(!host_turf)
throw EXCEPTION("attackby on APC when it's not on a turf")
- return
+ return ITEM_INTERACT_COMPLETE
if(host_turf.intact)
to_chat(user, "You must remove the floor plating in front of the APC first!")
- return
+ return ITEM_INTERACT_COMPLETE
else if(terminal) // it already have terminal
to_chat(user, "This APC is already wired!")
- return
+ return ITEM_INTERACT_COMPLETE
else if(!has_electronics())
to_chat(user, "There is nothing to wire!")
- return
+ return ITEM_INTERACT_COMPLETE
- var/obj/item/stack/cable_coil/C = W
+ var/obj/item/stack/cable_coil/C = used
if(C.get_amount() < 10)
to_chat(user, "You need ten lengths of cable for APC!")
- return
+ return ITEM_INTERACT_COMPLETE
user.visible_message("[user.name] adds cables to the APC frame.", \
"You start adding cables to the APC frame...")
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
if(do_after(user, 20, target = src))
if(C.get_amount() < 10 || !C)
- return
+ return ITEM_INTERACT_COMPLETE
if(C.get_amount() >= 10 && !terminal && opened && has_electronics())
var/turf/T = get_turf(src)
var/obj/structure/cable/N = T.get_cable_node()
if(prob(50) && electrocute_mob(usr, N, N, 1, TRUE))
do_sparks(5, TRUE, src)
- return
+ return ITEM_INTERACT_COMPLETE
C.use(10)
to_chat(user, "You add cables to the APC frame.")
make_terminal()
terminal.connect_to_network()
- else if(istype(W, /obj/item/apc_electronics) && opened)
+ return ITEM_INTERACT_COMPLETE
+
+ else if(istype(used, /obj/item/apc_electronics) && opened)
if(has_electronics()) // there are already electronicks inside
to_chat(user, "You cannot put the board inside, there already is one!")
- return
+ return ITEM_INTERACT_COMPLETE
else if(stat & BROKEN)
to_chat(user, "You cannot put the board inside, the frame is damaged!")
- return
+ return ITEM_INTERACT_COMPLETE
- user.visible_message("[user.name] inserts [W] into [src].", \
- "You start to insert [W] into the frame...")
+ user.visible_message("[user.name] inserts [used] into [src].", \
+ "You start to insert [used] into the frame...")
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
if(do_after(user, 10, target = src))
if(!has_electronics())
electronics_state = APC_ELECTRONICS_INSTALLED
locked = FALSE
- to_chat(user, "You place [W] inside the frame.")
- qdel(W)
+ to_chat(user, "You place [used] inside the frame.")
+ qdel(used)
- else if(istype(W, /obj/item/mounted/frame/apc_frame) && opened)
+ return ITEM_INTERACT_COMPLETE
+
+ else if(istype(used, /obj/item/mounted/frame/apc_frame) && opened)
if(!(stat & BROKEN || opened == APC_COVER_OFF || obj_integrity < max_integrity)) // There is nothing to repair
to_chat(user, "You found no reason for repairing this APC.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!(stat & BROKEN) && opened == APC_COVER_OFF) // Cover is the only thing broken, we do not need to remove elctronicks to replace cover
user.visible_message("[user.name] replaces missing APC's cover.",\
"You begin to replace APC's cover...")
if(do_after(user, 20, target = src)) // replacing cover is quicker than replacing whole frame
to_chat(user, "You replace missing APC's cover.")
- qdel(W)
+ qdel(used)
opened = APC_OPENED
update_icon()
- return
+ return ITEM_INTERACT_COMPLETE
if(has_electronics())
to_chat(user, "You cannot repair this APC until you remove the electronics still inside!")
- return
+ return ITEM_INTERACT_COMPLETE
user.visible_message("[user.name] replaces the damaged APC frame with a new one.",\
"You begin to replace the damaged APC frame...")
if(do_after(user, 50, target = src))
to_chat(user, "You replace the damaged APC frame with a new one.")
- qdel(W)
+ qdel(used)
stat &= ~BROKEN
obj_integrity = max_integrity
if(opened == APC_COVER_OFF)
opened = APC_OPENED
update_icon()
- return
+ return ITEM_INTERACT_COMPLETE
else
return ..()
diff --git a/code/modules/power/cables/terminal.dm b/code/modules/power/cables/terminal.dm
index c459f7864ead..23ab1950d556 100644
--- a/code/modules/power/cables/terminal.dm
+++ b/code/modules/power/cables/terminal.dm
@@ -77,8 +77,9 @@
qdel(src)
-/obj/machinery/power/terminal/attackby__legacy__attackchain(obj/item/W, mob/living/user, params)
- if(istype(W, /obj/item/wirecutters))
- dismantle(user, W)
+/obj/machinery/power/terminal/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/wirecutters))
+ dismantle(user, used)
+ return ITEM_INTERACT_COMPLETE
else
return ..()
diff --git a/code/modules/power/engines/singularity/collector.dm b/code/modules/power/engines/singularity/collector.dm
index 4dd7d9110cbe..971b11ff0edd 100644
--- a/code/modules/power/engines/singularity/collector.dm
+++ b/code/modules/power/engines/singularity/collector.dm
@@ -65,24 +65,23 @@
else
disconnect_from_network()
-
-/obj/machinery/power/rad_collector/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/tank/internals/plasma))
+/obj/machinery/power/rad_collector/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/tank/internals/plasma))
if(!anchored)
to_chat(user, "[src] needs to be secured to the floor first.")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
if(loaded_tank)
to_chat(user, "There's already a plasma tank loaded.")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
if(user.drop_item())
- loaded_tank = I
- I.forceMove(src)
+ loaded_tank = used
+ used.forceMove(src)
update_icons()
- else if(I.tool_behaviour == TOOL_CROWBAR)
+ else if(used.tool_behaviour == TOOL_CROWBAR)
if(loaded_tank && !locked)
eject()
- return TRUE
- else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/card/id) || istype(used, /obj/item/pda))
if(allowed(user))
if(active)
locked = !locked
@@ -92,7 +91,8 @@
to_chat(user, "The controls can only be locked when [src] is active")
else
to_chat(user, "Access denied!")
- return TRUE
+
+ return ITEM_INTERACT_COMPLETE
else
return ..()
diff --git a/code/modules/power/engines/singularity/containment_field.dm b/code/modules/power/engines/singularity/containment_field.dm
index cfec3f374779..6fdb50dfb3a8 100644
--- a/code/modules/power/engines/singularity/containment_field.dm
+++ b/code/modules/power/engines/singularity/containment_field.dm
@@ -35,9 +35,9 @@
shock_field(user)
return 1
-/obj/machinery/field/containment/attackby__legacy__attackchain(obj/item/W, mob/user, params)
+/obj/machinery/field/containment/item_interaction(mob/living/user, obj/item/used, list/modifiers)
shock(user)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
/obj/machinery/field/containment/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
diff --git a/code/modules/power/engines/singularity/emitter.dm b/code/modules/power/engines/singularity/emitter.dm
index 1e1af0ed3ecb..0e3d79c6f7f3 100644
--- a/code/modules/power/engines/singularity/emitter.dm
+++ b/code/modules/power/engines/singularity/emitter.dm
@@ -146,17 +146,17 @@
if(!anchored)
step(src, get_dir(M, src))
-/obj/machinery/power/emitter/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(!istype(I, /obj/item/card/id) && !istype(I, /obj/item/pda))
+/obj/machinery/power/emitter/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(!istype(used, /obj/item/card/id) && !istype(used, /obj/item/pda))
return ..()
if(emagged)
to_chat(user, "The lock seems to be broken.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!allowed(user))
to_chat(user, "Access denied.")
- return
+ return ITEM_INTERACT_COMPLETE
if(active)
locked = !locked
@@ -165,6 +165,8 @@
locked = FALSE //just in case it somehow gets locked
to_chat(user, "The controls can only be locked when [src] is online!")
+ return ITEM_INTERACT_COMPLETE
+
/obj/machinery/power/emitter/wrench_act(mob/living/user, obj/item/I)
. = TRUE
if(active)
diff --git a/code/modules/power/engines/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/engines/singularity/particle_accelerator/particle_accelerator.dm
index a64c70fd5362..e86ef93bc538 100644
--- a/code/modules/power/engines/singularity/particle_accelerator/particle_accelerator.dm
+++ b/code/modules/power/engines/singularity/particle_accelerator/particle_accelerator.dm
@@ -241,18 +241,19 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin
return
dir = turn(dir, 270)
-/obj/machinery/particle_accelerator/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(!iscoil(W))
+/obj/machinery/particle_accelerator/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(!iscoil(used))
return ..()
if(construction_state == ACCELERATOR_WRENCHED)
- var/obj/item/stack/cable_coil/C = W
+ var/obj/item/stack/cable_coil/C = used
if(C.use(1))
playsound(loc, C.usesound, 50, 1)
- user.visible_message("[user] adds wires to [src].", \
- "You add some wires.")
+ user.visible_message("[user] adds wires to [src].", "You add some wires.")
construction_state = ACCELERATOR_WIRED
update_icon()
+ return ITEM_INTERACT_COMPLETE
+
/obj/machinery/particle_accelerator/screwdriver_act(mob/user, obj/item/I)
if(construction_state != ACCELERATOR_WIRED && construction_state != ACCELERATOR_READY)
return
diff --git a/code/modules/power/engines/supermatter/supermatter.dm b/code/modules/power/engines/supermatter/supermatter.dm
index 52660563a0c5..dfb6ee07deff 100644
--- a/code/modules/power/engines/supermatter/supermatter.dm
+++ b/code/modules/power/engines/supermatter/supermatter.dm
@@ -784,22 +784,22 @@
playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE)
Consume(nom)
-/obj/machinery/atmospherics/supermatter_crystal/attackby__legacy__attackchain(obj/item/I, mob/living/user, params)
- if(!istype(I) || (I.flags & ABSTRACT) || !istype(user))
- return
- if(moveable && default_unfasten_wrench(user, I, time = 20))
- return
+/obj/machinery/atmospherics/supermatter_crystal/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(!istype(used) || (used.flags & ABSTRACT) || !istype(user))
+ return ITEM_INTERACT_COMPLETE
+ if(moveable && default_unfasten_wrench(user, used, time = 20))
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/scalpel/supermatter))
+ if(istype(used, /obj/item/scalpel/supermatter))
if(!ishuman(user))
- return
+ return ITEM_INTERACT_COMPLETE
var/mob/living/carbon/human/H = user
- var/obj/item/scalpel/supermatter/scalpel = I
+ var/obj/item/scalpel/supermatter/scalpel = used
if(!scalpel.uses_left)
to_chat(H, "[scalpel] isn't sharp enough to carve a sliver off of [src]!")
- return
+ return ITEM_INTERACT_COMPLETE
var/obj/item/nuke_core/supermatter_sliver/sliver = carve_sliver(H)
if(sliver)
@@ -816,20 +816,20 @@
tongs.item_state = "supermatter_tongs_loaded"
to_chat(H, "You pick up [sliver] with [tongs]!")
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/supermatter_halberd))
+ if(istype(used, /obj/item/supermatter_halberd))
carve_sliver(user)
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(I, /obj/item/retractor/supermatter))
- to_chat(user, "[I] bounces off [src], you need to cut a sliver off first!")
+ if(istype(used, /obj/item/retractor/supermatter))
+ to_chat(user, "[used] bounces off [src], you need to cut a sliver off first!")
else if(user.drop_item())
- user.visible_message("As [user] touches [src] with \a [I], silence fills the room...",\
- "You touch [src] with [I], and everything suddenly goes silent.\n[I] flashes into dust as you flinch away from [src].",\
+ user.visible_message("As [user] touches [src] with \a [used], silence fills the room...",\
+ "You touch [src] with [used], and everything suddenly goes silent.\n[used] flashes into dust as you flinch away from [src].",\
"Everything suddenly goes silent.")
- investigate_log("has been attacked ([I]) by [key_name(user)]", "supermatter")
- Consume(I)
+ investigate_log("has been attacked ([used]) by [key_name(user)]", "supermatter")
+ Consume(used)
playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE)
radiation_pulse(src, 150, 4)
diff --git a/code/modules/power/engines/tesla/coil.dm b/code/modules/power/engines/tesla/coil.dm
index 93078385b0bc..5bf6cf406a94 100644
--- a/code/modules/power/engines/tesla/coil.dm
+++ b/code/modules/power/engines/tesla/coil.dm
@@ -43,11 +43,12 @@
if(in_range(user, src) || isobserver(user))
. += "The status display reads: Power generation at [input_power_multiplier*100]%.
Shock interval at [zap_cooldown*0.1] seconds."
-/obj/machinery/power/tesla_coil/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/assembly/signaler) && panel_open)
+/obj/machinery/power/tesla_coil/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/assembly/signaler) && panel_open)
wires.Interact(user)
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/power/tesla_coil/crowbar_act(mob/user, obj/item/I)
. = TRUE
@@ -129,9 +130,11 @@
component_parts += new /obj/item/stock_parts/capacitor(null)
RefreshParts()
-/obj/machinery/power/grounding_rod/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(exchange_parts(user, W))
- return
+/obj/machinery/power/grounding_rod/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(exchange_parts(user, used))
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/power/grounding_rod/screwdriver_act(mob/user, obj/item/I)
. = TRUE
diff --git a/code/modules/power/generators/portable generators/pacman.dm b/code/modules/power/generators/portable generators/pacman.dm
index 12705003760b..ee7a0c89c8af 100644
--- a/code/modules/power/generators/portable generators/pacman.dm
+++ b/code/modules/power/generators/portable generators/pacman.dm
@@ -191,19 +191,19 @@
emagged = TRUE
return TRUE
-/obj/machinery/power/port_gen/pacman/attackby__legacy__attackchain(obj/item/O as obj, mob/user as mob)
- if(istype(O, sheet_path))
- var/obj/item/stack/addstack = O
+/obj/machinery/power/port_gen/pacman/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, sheet_path))
+ var/obj/item/stack/addstack = used
var/amount = min((max_sheets - sheets), addstack.amount)
if(amount < 1)
to_chat(user, "[src] is full!")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You add [amount] sheet\s to [src].")
sheets += amount
addstack.use(amount)
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/power/generators/treadmill.dm b/code/modules/power/generators/treadmill.dm
index f57b6ee3b4f3..1fe399551f04 100644
--- a/code/modules/power/generators/treadmill.dm
+++ b/code/modules/power/generators/treadmill.dm
@@ -110,12 +110,13 @@
spawn(100)
stat &= ~BROKEN
-/obj/machinery/power/treadmill/attackby__legacy__attackchain(obj/item/W, mob/user)
- if(default_unfasten_wrench(user, W, time = 60))
+/obj/machinery/power/treadmill/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_unfasten_wrench(user, used, time = 60))
on_anchor_changed()
speed = 0
update_icon()
- return
+ return ITEM_INTERACT_COMPLETE
+
return ..()
#undef BASE_MOVE_DELAY
diff --git a/code/modules/power/generators/turbine.dm b/code/modules/power/generators/turbine.dm
index 0b15beb5fbc6..6c74a82fbab4 100644
--- a/code/modules/power/generators/turbine.dm
+++ b/code/modules/power/generators/turbine.dm
@@ -126,8 +126,8 @@
E += M.rating
efficiency = E / 6
-/obj/machinery/power/compressor/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(default_change_direction_wrench(user, I))
+/obj/machinery/power/compressor/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_change_direction_wrench(user, used))
turbine = null
inturf = get_step(src, dir)
locate_machinery()
@@ -137,7 +137,8 @@
else
to_chat(user, "Turbine not connected.")
stat |= BROKEN
- return
+
+ return ITEM_INTERACT_COMPLETE
return ..()
@@ -328,11 +329,11 @@
return
. += image(icon, "turb-o", FLY_LAYER)
-/obj/machinery/power/turbine/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(default_deconstruction_screwdriver(user, initial(icon_state), initial(icon_state), I))
- return
+/obj/machinery/power/turbine/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_deconstruction_screwdriver(user, initial(icon_state), initial(icon_state), used))
+ return ITEM_INTERACT_COMPLETE
- if(default_change_direction_wrench(user, I))
+ if(default_change_direction_wrench(user, used))
compressor = null
outturf = get_step(src, dir)
locate_machinery()
@@ -342,10 +343,10 @@
else
to_chat(user, "Compressor not connected.")
stat |= BROKEN
- return
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_crowbar(user, I))
- return
+ if(default_deconstruction_crowbar(user, used))
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index 7a21e52a42b7..22fd1e4aa4d9 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -152,18 +152,22 @@ GLOBAL_LIST_EMPTY(gravity_generators)
update_icon()
// Step 2
-/obj/machinery/gravity_generator/main/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/gravity_generator/main/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(construction_state != GRAV_NEEDS_PLASTEEL)
return ..()
- if(istype(I, /obj/item/stack/sheet/plasteel))
- var/obj/item/stack/sheet/plasteel/PS = I
+
+ if(istype(used, /obj/item/stack/sheet/plasteel))
+ var/obj/item/stack/sheet/plasteel/PS = used
if(PS.amount < 10)
to_chat(user, "You need 10 sheets of plasteel.")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You add new plating to the framework.")
construction_state = GRAV_NEEDS_WRENCH
update_icon()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
// Step 3
/obj/machinery/gravity_generator/main/wrench_act(mob/living/user, obj/item/I)
diff --git a/code/modules/power/lights.dm b/code/modules/power/lights.dm
index bf048012cb6d..baa4e75f3615 100644
--- a/code/modules/power/lights.dm
+++ b/code/modules/power/lights.dm
@@ -96,19 +96,19 @@
transfer_fingerprints_to(newlight)
qdel(src)
-/obj/machinery/light_construct/attackby__legacy__attackchain(obj/item/W, mob/living/user, params)
+/obj/machinery/light_construct/item_interaction(mob/living/user, obj/item/used, list/modifiers)
add_fingerprint(user)
- if(istype(W, /obj/item/stack/cable_coil))
+ if(istype(used, /obj/item/stack/cable_coil))
if(stage != LIGHT_CONSTRUCT_EMPTY_FRAME)
- return
- var/obj/item/stack/cable_coil/coil = W
+ return ITEM_INTERACT_COMPLETE
+ var/obj/item/stack/cable_coil/coil = used
coil.use(1)
stage = LIGHT_CONSTRUCT_WIRED
update_icon(UPDATE_ICON_STATE)
playsound(loc, coil.usesound, 50, 1)
user.visible_message("[user.name] adds wires to [src].", \
"You add wires to [src].", "You hear a noise.")
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
@@ -593,22 +593,22 @@
// attack with item - insert light (if right type), otherwise try to break the light
-/obj/machinery/light/attackby__legacy__attackchain(obj/item/W, mob/living/user, params)
+/obj/machinery/light/item_interaction(mob/living/user, obj/item/used, list/modifiers)
user.changeNext_move(CLICK_CD_MELEE) // This is an ugly hack and I hate it forever
//Light replacer code
- if(istype(W, /obj/item/lightreplacer))
- var/obj/item/lightreplacer/LR = W
+ if(istype(used, /obj/item/lightreplacer))
+ var/obj/item/lightreplacer/LR = used
LR.ReplaceLight(src, user)
- return
+ return ITEM_INTERACT_COMPLETE
// Attack with Spray Can! Coloring time.
- if(istype(W, /obj/item/toy/crayon/spraycan))
- var/obj/item/toy/crayon/spraycan/spraycan = W
+ if(istype(used, /obj/item/toy/crayon/spraycan))
+ var/obj/item/toy/crayon/spraycan/spraycan = used
// quick check to disable capped spraypainting, aesthetic reasons
if(spraycan.capped)
to_chat(user, "You can't spraypaint [src] with the cap still on!")
- return
+ return ITEM_INTERACT_COMPLETE
var/list/hsl = rgb2hsl(hex2num(copytext(spraycan.colour, 2, 4)), hex2num(copytext(spraycan.colour, 4, 6)), hex2num(copytext(spraycan.colour, 6, 8)))
hsl[3] = max(hsl[3], 0.4)
var/list/rgb = hsl2rgb(arglist(hsl))
@@ -617,15 +617,15 @@
to_chat(user, "You change [src]'s light bulb color.")
brightness_color = new_color
update(TRUE, TRUE, FALSE)
- return
+ return ITEM_INTERACT_COMPLETE
// attempt to insert light
- if(istype(W, /obj/item/light))
+ if(istype(used, /obj/item/light))
if(status != LIGHT_EMPTY)
to_chat(user, "There is a [fitting] already inserted.")
else
add_fingerprint(user)
- var/obj/item/light/L = W
+ var/obj/item/light/L = used
if(istype(L, light_type))
status = L.status
to_chat(user, "You insert [L].")
@@ -649,18 +649,18 @@
explode()
else
to_chat(user, "This type of light requires a [fitting].")
- return
+ return ITEM_INTERACT_COMPLETE
// attempt to break the light
//If xenos decide they want to smash a light bulb with a toolbox, who am I to stop them? /N
if(status != LIGHT_BROKEN && status != LIGHT_EMPTY)
user.do_attack_animation(src)
- if(prob(1 + W.force * 5))
+ if(prob(1 + used.force * 5))
user.visible_message("[user] smashed the light!", "You hit the light, and it smashes!", \
"You hear the tinkle of breaking glass.")
- if(on && (W.flags & CONDUCT))
+ if(on && (used.flags & CONDUCT))
if(prob(12))
electrocute_mob(user, get_area(src), src, 0.3, TRUE)
break_light_tube()
@@ -668,18 +668,20 @@
user.visible_message("[user] hits the light.", "You hit the light.", \
"You hear someone hitting a light.")
playsound(loc, 'sound/effects/glasshit.ogg', 75, 1)
- return
+
+ return ITEM_INTERACT_COMPLETE
// attempt to stick weapon into light socket
if(status == LIGHT_EMPTY)
- if(has_power() && (W.flags & CONDUCT))
+ if(has_power() && (used.flags & CONDUCT))
do_sparks(3, 1, src)
if(prob(75)) // If electrocuted
electrocute_mob(user, get_area(src), src, rand(0.7, 1), TRUE)
to_chat(user, "You are electrocuted by [src]!")
else // If not electrocuted
- to_chat(user, "You stick [W] into the light socket!")
- return
+ to_chat(user, "You stick [used] into the light socket!")
+
+ return ITEM_INTERACT_COMPLETE
return ..()
@@ -712,12 +714,14 @@
transfer_fingerprints_to(newlight)
qdel(src)
-/obj/machinery/light/attacked_by__legacy__attackchain(obj/item/I, mob/living/user)
- ..()
+/obj/machinery/light/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(status == LIGHT_BROKEN || status == LIGHT_EMPTY)
- if(on && (I.flags & CONDUCT))
+ if(on && (used.flags & CONDUCT))
if(prob(12))
electrocute_mob(user, get_area(src), src, 0.3, TRUE)
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/light/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
. = ..()
diff --git a/code/modules/power/power_machine.dm b/code/modules/power/power_machine.dm
index 4f3903da067a..76f7bf4139a4 100644
--- a/code/modules/power/power_machine.dm
+++ b/code/modules/power/power_machine.dm
@@ -76,17 +76,18 @@
// attach a wire to a power machine - leads from the turf you are standing on
//almost never called, overwritten by all power machines but terminal and generator
-/obj/machinery/power/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/coil = I
+/obj/machinery/power/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/coil = used
var/turf/T = user.loc
if(T.intact || !isfloorturf(T))
- return
+ return ITEM_INTERACT_COMPLETE
if(get_dist(src, user) > 1)
- return
+ return ITEM_INTERACT_COMPLETE
coil.place_turf(T, user)
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
////////////////////////////////////////////////
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index fd247fe44eaf..b9583b065bdc 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -102,14 +102,14 @@
if(charge_level > 0)
. += "smes-og[charge_level]"
-/obj/machinery/power/smes/attackby__legacy__attackchain(obj/item/I, mob/user, params)
+/obj/machinery/power/smes/item_interaction(mob/living/user, obj/item/used, list/modifiers)
// Opening using screwdriver
- if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I))
+ if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), used))
update_icon()
- return
+ return ITEM_INTERACT_COMPLETE
// Changing direction using wrench
- if(default_change_direction_wrench(user, I))
+ if(default_change_direction_wrench(user, used))
terminal = null
var/turf/T = get_step(src, dir)
for(var/obj/machinery/power/terminal/term in T)
@@ -120,38 +120,38 @@
break
if(!terminal)
to_chat(user, "No power source found.")
- return
+ return ITEM_INTERACT_COMPLETE
stat &= ~BROKEN
update_icon()
- return
+ return ITEM_INTERACT_COMPLETE
// Building and linking a terminal
- if(istype(I, /obj/item/stack/cable_coil))
+ if(istype(used, /obj/item/stack/cable_coil))
var/dir = get_dir(user, src)
if(dir & (dir - 1)) // Checks for diagonal interaction
- return
+ return ITEM_INTERACT_COMPLETE
if(terminal) // Checks for an existing terminal
to_chat(user, "This SMES already has a power terminal!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!panel_open) // Checks to see if the panel is closed
to_chat(user, "You must open the maintenance panel first!")
- return
+ return ITEM_INTERACT_COMPLETE
var/turf/T = get_turf(user)
if(T.intact) // Checks to see if floor plating is present
to_chat(user, "You must first remove the floor plating!")
- return
+ return ITEM_INTERACT_COMPLETE
- var/obj/item/stack/cable_coil/C = I
+ var/obj/item/stack/cable_coil/C = used
if(C.get_amount() < 10)
to_chat(user, "You need more wires.")
- return
+ return ITEM_INTERACT_COMPLETE
if(user.loc == loc)
to_chat(user, "You must not be on the same tile as [src].")
- return
+ return ITEM_INTERACT_COMPLETE
// Direction the terminal will face to
var/temporary_direction = get_dir(user, src)
@@ -164,12 +164,12 @@
if(isspaceturf(temporary_location))
to_chat(user, "You can't build a terminal on space.")
- return
+ return ITEM_INTERACT_COMPLETE
else if(istype(temporary_location))
if(temporary_location.intact)
to_chat(user, "You must remove the floor plating first.")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You start adding cable to [src].")
playsound(loc, C.usesound, 50, TRUE)
@@ -190,23 +190,23 @@
make_terminal(user, temporary_direction, temporary_location)
terminal.connect_to_network()
stat &= ~BROKEN
- return
+ return ITEM_INTERACT_COMPLETE
// Disassembling the terminal
- if(istype(I, /obj/item/wirecutters) && terminal && panel_open)
+ if(istype(used, /obj/item/wirecutters) && terminal && panel_open)
var/turf/T = get_turf(terminal)
if(T.intact) //is the floor plating removed ?
to_chat(user, "You must first expose the power terminal!")
- return
+ return ITEM_INTERACT_COMPLETE
to_chat(user, "You begin to dismantle the power terminal...")
- playsound(src.loc, I.usesound, 50, TRUE)
+ playsound(src.loc, used.usesound, 50, TRUE)
- if(do_after(user, 5 SECONDS * I.toolspeed, target = src))
+ if(do_after(user, 5 SECONDS * used.toolspeed, target = src))
if(terminal && panel_open)
if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal, 1, TRUE)) // Animate the electrocution if uncautious and unlucky
do_sparks(5, TRUE, src)
- return
+ return ITEM_INTERACT_COMPLETE
// Returns wires on deletion of the terminal
new /obj/item/stack/cable_coil(T, 10)
@@ -215,11 +215,11 @@
"You cut the cables and dismantle the power terminal.")
inputting = FALSE // Set input FALSE when the terminal no longer exists
qdel(terminal)
- return
+ return ITEM_INTERACT_COMPLETE
// Crowbarring it !
- if(default_deconstruction_crowbar(user, I))
- return
+ if(default_deconstruction_crowbar(user, used))
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index c96ea19803e3..d5c6664fa692 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -234,35 +234,35 @@
add_fingerprint(usr)
-/obj/machinery/chem_dispenser/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/storage/part_replacer))
+/obj/machinery/chem_dispenser/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/part_replacer))
. = ..()
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
- if((istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/drinks)) && user.a_intent != INTENT_HARM)
+ if((istype(used, /obj/item/reagent_containers/glass) || istype(used, /obj/item/reagent_containers/drinks)) && user.a_intent != INTENT_HARM)
if(panel_open)
to_chat(user, "Close the maintenance panel first.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- to_chat(user, "[I] is stuck to you!")
- return
+ to_chat(user, "[used] is stuck to you!")
+ return ITEM_INTERACT_COMPLETE
- I.forceMove(src)
+ used.forceMove(src)
if(beaker)
- to_chat(usr, "You swap [I] with [beaker].")
+ to_chat(usr, "You swap [used] with [beaker].")
if(Adjacent(usr) && !issilicon(usr)) //Prevents telekinesis from putting in hand
user.put_in_hands(beaker)
else
beaker.forceMove(loc)
else
- to_chat(user, "You set [I] on the machine.")
- beaker = I
+ to_chat(user, "You set [used] on the machine.")
+ beaker = used
SStgui.update_uis(src) // update all UIs attached to src
update_icon(UPDATE_ICON_STATE)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm
index ecfb026025bf..e70641c9b119 100644
--- a/code/modules/reagents/chemistry/machinery/chem_heater.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm
@@ -62,22 +62,22 @@
else
stat |= NOPOWER
-/obj/machinery/chem_heater/attackby__legacy__attackchain(obj/item/I, mob/user)
- if(istype(I, /obj/item/reagent_containers/glass) && user.a_intent != INTENT_HARM)
+/obj/machinery/chem_heater/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/reagent_containers/glass) && user.a_intent != INTENT_HARM)
if(beaker)
to_chat(user, "A beaker is already loaded into the machine.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- to_chat(user, "[I] is stuck to you!")
- return
+ to_chat(user, "[used] is stuck to you!")
+ return ITEM_INTERACT_COMPLETE
- beaker = I
- I.forceMove(src)
+ beaker = used
+ used.forceMove(src)
to_chat(user, "You add the beaker to the machine!")
icon_state = "mixer1b"
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 8aba2a20252f..8c138aec169e 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -114,45 +114,49 @@
return
update_icon()
-/obj/machinery/chem_master/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/storage/part_replacer))
+/obj/machinery/chem_master/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
if(panel_open)
to_chat(user, "You can't use [src] while it's panel is opened!")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if((istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/drinks/drinkingglass)) && user.a_intent != INTENT_HARM)
+ if((istype(used, /obj/item/reagent_containers/glass) || istype(used, /obj/item/reagent_containers/drinks/drinkingglass)) && user.a_intent != INTENT_HARM)
if(!user.drop_item())
- to_chat(user, "[I] is stuck to you!")
- return
+ to_chat(user, "[used] is stuck to you!")
+ return ITEM_INTERACT_COMPLETE
- I.forceMove(src)
+ used.forceMove(src)
if(beaker)
- to_chat(usr, "You swap [I] with [beaker] inside.")
+ to_chat(usr, "You swap [used] with [beaker] inside.")
if(Adjacent(usr) && !issilicon(usr)) //Prevents telekinesis from putting in hand
user.put_in_hands(beaker)
else
beaker.forceMove(loc)
else
- to_chat(user, "You add [I] to the machine.")
- beaker = I
+ to_chat(user, "You add [used] to the machine.")
+ beaker = used
SStgui.update_uis(src)
update_icon()
- else if(istype(I, /obj/item/storage/pill_bottle))
+ return ITEM_INTERACT_COMPLETE
+
+ else if(istype(used, /obj/item/storage/pill_bottle))
if(loaded_pill_bottle)
to_chat(user, "A [loaded_pill_bottle] is already loaded into the machine.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- to_chat(user, "[I] is stuck to you!")
- return
+ to_chat(user, "[used] is stuck to you!")
+ return ITEM_INTERACT_COMPLETE
- loaded_pill_bottle = I
- I.forceMove(src)
- to_chat(user, "You add [I] into the dispenser slot!")
+ loaded_pill_bottle = used
+ used.forceMove(src)
+ to_chat(user, "You add [used] into the dispenser slot!")
SStgui.update_uis(src)
+ return ITEM_INTERACT_COMPLETE
+
else
return ..()
diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm
index 6c48a64024e3..1151e4e24648 100644
--- a/code/modules/reagents/chemistry/machinery/pandemic.dm
+++ b/code/modules/reagents/chemistry/machinery/pandemic.dm
@@ -383,24 +383,26 @@
/obj/machinery/computer/pandemic/attack_ghost(mob/user)
ui_interact(user)
-/obj/machinery/computer/pandemic/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(default_unfasten_wrench(user, I, time = 4 SECONDS))
+/obj/machinery/computer/pandemic/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(default_unfasten_wrench(user, used, time = 4 SECONDS))
power_change()
return
- if((istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER)) && user.a_intent != INTENT_HARM)
+ if((istype(used, /obj/item/reagent_containers) && (used.container_type & OPENCONTAINER)) && user.a_intent != INTENT_HARM)
if(stat & (NOPOWER|BROKEN))
- return
+ return ITEM_INTERACT_COMPLETE
if(beaker)
to_chat(user, "A beaker is already loaded into the machine!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- return
+ return ITEM_INTERACT_COMPLETE
- beaker = I
+ beaker = used
beaker.loc = src
to_chat(user, "You add the beaker to the machine.")
SStgui.update_uis(src, TRUE)
icon_state = "pandemic1"
+
+ return ITEM_INTERACT_COMPLETE
else
return ..()
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index 291e14081303..47081c7aca9b 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -157,44 +157,44 @@
return
default_unfasten_wrench(user, I)
-/obj/machinery/reagentgrinder/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/storage/part_replacer))
- ..()
+/obj/machinery/reagentgrinder/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/part_replacer))
+ . = ..()
SStgui.update_uis(src)
- return
+ return ITEM_INTERACT_COMPLETE
- if((istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER)) && user.a_intent != INTENT_HARM)
+ if((istype(used, /obj/item/reagent_containers) && (used.container_type & OPENCONTAINER)) && user.a_intent != INTENT_HARM)
if(beaker)
to_chat(user, "There's already a container inside.")
else if(panel_open)
to_chat(user, "Close the maintenance panel first.")
else
if(!user.drop_item())
- return FALSE
+ return ITEM_INTERACT_COMPLETE
- beaker = I
+ beaker = used
beaker.loc = src
update_icon(UPDATE_ICON_STATE)
SStgui.update_uis(src)
- return TRUE // No afterattack
+ return ITEM_INTERACT_COMPLETE
- if(is_type_in_list(I, dried_items))
- if(istype(I, /obj/item/food/grown))
- var/obj/item/food/grown/G = I
+ if(is_type_in_list(used, dried_items))
+ if(istype(used, /obj/item/food/grown))
+ var/obj/item/food/grown/G = used
if(!G.dry)
to_chat(user, "You must dry that first!")
- return FALSE
+ return ITEM_INTERACT_COMPLETE
if(length(holdingitems) >= limit)
to_chat(usr, "The machine cannot hold anymore items.")
- return FALSE
+ return ITEM_INTERACT_COMPLETE
// Fill machine with a bag!
- if(istype(I, /obj/item/storage/bag))
- var/obj/item/storage/bag/B = I
+ if(istype(used, /obj/item/storage/bag))
+ var/obj/item/storage/bag/B = used
if(!length(B.contents))
to_chat(user, "[B] is empty.")
- return FALSE
+ return ITEM_INTERACT_COMPLETE
var/original_contents_len = length(B.contents)
@@ -208,7 +208,7 @@
if(length(B.contents) == original_contents_len)
to_chat(user, "Nothing in [B] can be put into the All-In-One grinder.")
- return FALSE
+ return ITEM_INTERACT_COMPLETE
else if(!length(B.contents))
to_chat(user, "You empty all of [B]'s contents into the All-In-One grinder.")
@@ -216,20 +216,22 @@
to_chat(user, "You empty some of [B]'s contents into the All-In-One grinder.")
SStgui.update_uis(src)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items))
+ if(!is_type_in_list(used, blend_items) && !is_type_in_list(used, juice_items))
if(user.a_intent == INTENT_HARM)
return ..()
else
to_chat(user, "Cannot refine into a reagent!")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
if(user.drop_item())
- I.loc = src
- holdingitems += I
+ used.loc = src
+ holdingitems += used
SStgui.update_uis(src)
- return FALSE
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/reagentgrinder/attack_ai(mob/user)
return FALSE
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index 03755059d7c7..d7b27718888e 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -57,29 +57,28 @@ GLOBAL_LIST_EMPTY(conveyor_switches)
update_move_direction()
// attack with item, place item on conveyor
-/obj/machinery/conveyor/attackby__legacy__attackchain(obj/item/I, mob/user)
+/obj/machinery/conveyor/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(stat & BROKEN)
return ..()
- if(istype(I, /obj/item/conveyor_switch_construct))
- var/obj/item/conveyor_switch_construct/S = I
+ if(istype(used, /obj/item/conveyor_switch_construct))
+ var/obj/item/conveyor_switch_construct/S = used
if(S.id == id)
return ..()
for(var/obj/machinery/conveyor_switch/CS in GLOB.conveyor_switches)
if(CS.id == id)
CS.conveyors -= src
id = S.id
- to_chat(user, "You link [I] with [src].")
- return
+ to_chat(user, "You link [used] with [src].")
+ return ITEM_INTERACT_COMPLETE
if(user.a_intent == INTENT_HELP)
if(user.drop_item())
- I.forceMove(loc)
- return
+ used.forceMove(loc)
+ return ITEM_INTERACT_COMPLETE
return ..()
-
/obj/machinery/conveyor/crowbar_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 33a01ea0c848..072a0750826b 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -123,23 +123,23 @@
disposal.update()
// attack by item places it in to disposal
-/obj/machinery/disposal/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(stat & BROKEN || !user || I.flags & ABSTRACT)
- return
+/obj/machinery/disposal/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(stat & BROKEN || !user || used.flags & ABSTRACT)
+ return ITEM_INTERACT_COMPLETE
if(user.a_intent != INTENT_HELP)
return ..()
src.add_fingerprint(user)
- if(istype(I, /obj/item/melee/energy/blade))
+ if(istype(used, /obj/item/melee/energy/blade))
to_chat(user, "You can't place that item inside the disposal unit.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(isstorage(I))
- var/obj/item/storage/S = I
+ if(isstorage(used))
+ var/obj/item/storage/S = used
if(!S.removal_allowed_check(user))
- return
+ return ITEM_INTERACT_COMPLETE
if((S.allow_quick_empty || S.allow_quick_gather) && length(S.contents))
S.hide_from(user)
@@ -152,15 +152,15 @@
S.remove_from_storage(O, src)
S.update_icon() // For content-sensitive icons
update()
- return
+ return ITEM_INTERACT_COMPLETE
// Borg using their gripper to throw stuff away.
- if(istype(I, /obj/item/gripper/))
- var/obj/item/gripper/gripper = I
+ if(istype(used, /obj/item/gripper))
+ var/obj/item/gripper/gripper = used
// Gripper is empty.
if(!gripper.gripped_item)
to_chat(user, "There's nothing in your gripper to throw away!")
- return
+ return ITEM_INTERACT_COMPLETE
gripper.gripped_item.forceMove(src)
user.visible_message(
@@ -168,14 +168,14 @@
"You place [gripper.gripped_item] into the disposal unit.",
"You hear someone dropping something into a disposal unit."
)
- return
+ return ITEM_INTERACT_COMPLETE
// Someone has a mob in a grab.
- var/obj/item/grab/G = I
+ var/obj/item/grab/G = used
if(istype(G))
// If there's not actually a mob in the grab, stop it. Get some help.
if(!ismob(G.affecting))
- return
+ return ITEM_INTERACT_COMPLETE
var/mob/GM = G.affecting
user.visible_message(
@@ -186,7 +186,7 @@
// Abort if the target manages to scurry away.
if(!do_after(user, 2 SECONDS, target = GM))
- return
+ return ITEM_INTERACT_COMPLETE
GM.forceMove(src)
user.visible_message(
@@ -197,20 +197,22 @@
qdel(G)
update()
add_attack_logs(user, GM, "Disposal'ed", !GM.ckey ? null : ATKLOG_ALL)
- return
+ return ITEM_INTERACT_COMPLETE
- if(!user.drop_item() || QDELETED(I))
- return
+ if(!user.drop_item() || QDELETED(used))
+ return ITEM_INTERACT_COMPLETE
// If we're here, it's an item without any special interactions, drop it in the bin without any further delay.
- I.forceMove(src)
+ used.forceMove(src)
user.visible_message(
- "[user] places [I] into the disposal unit.",
- "You place [I] into the disposal unit.",
+ "[user] places [used] into the disposal unit.",
+ "You place [used] into the disposal unit.",
"You hear someone dropping something into a disposal unit."
)
update()
+ return ITEM_INTERACT_COMPLETE
+
/obj/machinery/disposal/screwdriver_act(mob/user, obj/item/I)
if(mode != DISPOSALS_OFF) // It's on
to_chat(user, "You need to turn the disposal unit off first!")
diff --git a/code/modules/research/backup_console.dm b/code/modules/research/backup_console.dm
index 8a14054b344f..b65126c16a59 100644
--- a/code/modules/research/backup_console.dm
+++ b/code/modules/research/backup_console.dm
@@ -38,21 +38,20 @@
SStgui.update_uis(src)
-/obj/machinery/computer/rnd_backup/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/disk/rnd_backup_disk) && istype(user, /mob/living/carbon/human))
+/obj/machinery/computer/rnd_backup/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/disk/rnd_backup_disk) && istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = user
- if(!H.drop_item_to_ground(O))
- return TRUE
+ if(!H.drop_item_to_ground(used))
+ return ITEM_INTERACT_COMPLETE
- O.forceMove(src)
- inserted_disk = O
- to_chat(user, "You insert [O] into [src].")
+ used.forceMove(src)
+ inserted_disk = used
+ to_chat(user, "You insert [used] into [src].")
SStgui.update_uis(src)
- return TRUE
+ return ITEM_INTERACT_COMPLETE
return ..()
-
/obj/machinery/computer/rnd_backup/proc/eject_disk()
if(!inserted_disk)
return
diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm
index 1b07264d9e9f..40d0a9e4433a 100644
--- a/code/modules/research/circuitprinter.dm
+++ b/code/modules/research/circuitprinter.dm
@@ -74,16 +74,16 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
return round(A / max(1, (all_materials[M] * efficiency_coeff)))
-/obj/machinery/r_n_d/circuit_imprinter/attackby__legacy__attackchain(obj/item/O as obj, mob/user as mob, params)
- if(istype(O, /obj/item/storage/part_replacer))
+/obj/machinery/r_n_d/circuit_imprinter/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
if(panel_open)
to_chat(user, "You can't load [src] while it's opened.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(O.is_open_container())
- return FALSE
+ if(used.is_open_container())
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm
index ad5848af1257..65d6d3c5fd45 100644
--- a/code/modules/research/protolathe.dm
+++ b/code/modules/research/protolathe.dm
@@ -76,22 +76,22 @@ Note: Must be placed west/left of and R&D console to function.
A = A / max(1, (being_built.materials[M] * efficiency_coeff))
return A
-/obj/machinery/r_n_d/protolathe/attackby__legacy__attackchain(obj/item/O as obj, mob/user as mob, params)
- if(istype(O, /obj/item/storage/part_replacer))
+/obj/machinery/r_n_d/protolathe/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
- if(default_deconstruction_screwdriver(user, "protolathe_t", "protolathe", O))
+ if(default_deconstruction_screwdriver(user, "protolathe_t", "protolathe", used))
if(linked_console)
linked_console.linked_lathe = null
linked_console = null
- return FALSE
+ return ITEM_INTERACT_COMPLETE
if(panel_open)
to_chat(user, "You can't load [src] while it's opened.")
- return TRUE
+ return ITEM_INTERACT_COMPLETE
- if(O.is_open_container())
- return FALSE
+ if(used.is_open_container())
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index db9a789b5313..67db99680b61 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -179,27 +179,26 @@ won't update every console in existence) but it's more of a hassle to do. Also,
wait_message_timer = 0
return ..()
-/obj/machinery/computer/rdconsole/attackby__legacy__attackchain(obj/item/D as obj, mob/user as mob, params)
-
+/obj/machinery/computer/rdconsole/item_interaction(mob/living/user, obj/item/used, list/modifiers)
//Loading a disk into it.
- if(istype(D, /obj/item/disk))
+ if(istype(used, /obj/item/disk))
if(t_disk || d_disk)
to_chat(user, "A disk is already loaded into the machine.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(istype(D, /obj/item/disk/tech_disk)) t_disk = D
- else if(istype(D, /obj/item/disk/design_disk)) d_disk = D
+ if(istype(used, /obj/item/disk/tech_disk)) t_disk = used
+ else if(istype(used, /obj/item/disk/design_disk)) d_disk = used
else
to_chat(user, "Machine cannot accept disks in that format.")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- return
- D.loc = src
+ return ITEM_INTERACT_COMPLETE
+ used.loc = src
to_chat(user, "You add the disk to the machine!")
else if(!(linked_analyzer && linked_analyzer.busy) && !(linked_lathe && linked_lathe.busy) && !(linked_imprinter && linked_imprinter.busy))
- ..()
+ return ..()
+
SStgui.update_uis(src)
- return
/obj/machinery/computer/rdconsole/emag_act(user as mob)
if(!emagged)
diff --git a/code/modules/research/scientific_analyzer.dm b/code/modules/research/scientific_analyzer.dm
index 333cd5d0a3d6..694a4e00ce28 100644
--- a/code/modules/research/scientific_analyzer.dm
+++ b/code/modules/research/scientific_analyzer.dm
@@ -48,50 +48,53 @@ Note: Must be placed within 3 tiles of the R&D Console
return temp_list
-/obj/machinery/r_n_d/scientific_analyzer/attackby__legacy__attackchain(obj/item/O as obj, mob/user as mob, params)
- if(istype(O, /obj/item/storage/part_replacer))
+/obj/machinery/r_n_d/scientific_analyzer/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/storage/part_replacer))
return ..()
- if(default_deconstruction_screwdriver(user, "s_analyzer_t", "s_analyzer", O))
+ if(default_deconstruction_screwdriver(user, "s_analyzer_t", "s_analyzer", used))
if(linked_console)
linked_console.linked_analyzer = null
linked_console = null
- return
+ return ITEM_INTERACT_COMPLETE
- if(exchange_parts(user, O))
- return
+ // TODO: Almost positive this doesn't need to do the same exchange parts shit as /obj/machinery
+ if(exchange_parts(user, used))
+ return ITEM_INTERACT_COMPLETE
- if(default_deconstruction_crowbar(user, O))
- return
+ if(default_deconstruction_crowbar(user, used))
+ return ITEM_INTERACT_COMPLETE
if(!linked_console)
to_chat(user, "[src] must be linked to an R&D console first!")
- return
+ return ITEM_INTERACT_COMPLETE
if(busy)
to_chat(user, "[src] is busy right now.")
- return
+ return ITEM_INTERACT_COMPLETE
- if(isitem(O) && !loaded_item)
- if(!O.origin_tech)
+ if(isitem(used) && !loaded_item)
+ if(!used.origin_tech)
to_chat(user, "This doesn't seem to have a tech origin!")
- return
+ return ITEM_INTERACT_COMPLETE
- var/list/temp_tech = ConvertReqString2List(O.origin_tech)
+ var/list/temp_tech = ConvertReqString2List(used.origin_tech)
if(length(temp_tech) == 0)
to_chat(user, "You cannot deconstruct this item!")
- return
+ return ITEM_INTERACT_COMPLETE
if(!user.drop_item())
- to_chat(user, "[O] is stuck to your hand, you cannot put it in [src]!")
- return
+ to_chat(user, "[used] is stuck to your hand, you cannot put it in [src]!")
+ return ITEM_INTERACT_COMPLETE
busy = TRUE
- loaded_item = O
- O.loc = src
- to_chat(user, "You add [O] to [src]!")
+ loaded_item = used
+ used.loc = src
+ to_chat(user, "You add [used] to [src]!")
SStgui.update_uis(linked_console)
flick("s_analyzer_la", src)
spawn(10)
icon_state = "s_analyzer_l"
busy = FALSE
+
+ return ITEM_INTERACT_COMPLETE
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index 84a60c49cf08..e33810f4398f 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -149,21 +149,21 @@
return
return ..()
-/obj/machinery/computer/camera_advanced/xenobio/attackby__legacy__attackchain(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/food/monkeycube))
+/obj/machinery/computer/camera_advanced/xenobio/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/food/monkeycube))
if(user.drop_item())
monkeys++
- to_chat(user, "You feed [O] to [src]. It now has [monkeys] monkey cubes stored.")
- qdel(O)
- return
- else if(istype(O, /obj/item/slimepotion/slime))
+ to_chat(user, "You feed [used] to [src]. It now has [monkeys] monkey cubes stored.")
+ qdel(used)
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/slimepotion/slime))
if(!user.drop_item())
- return
- to_chat(user, "You load [O] in the console's potion slot[current_potion ? ", replacing the one that was there before" : ""].")
- insert_potion(O, user)
- return
- else if(istype(O, /obj/item/storage/bag) || istype(O, /obj/item/storage/box))
- var/obj/item/storage/P = O
+ return ITEM_INTERACT_COMPLETE
+ to_chat(user, "You load [used] in the console's potion slot[current_potion ? ", replacing the one that was there before" : ""].")
+ insert_potion(used, user)
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/storage/bag) || istype(used, /obj/item/storage/box))
+ var/obj/item/storage/P = used
var/loaded = 0
for(var/obj/item/food/monkeycube/MC in P.contents)
loaded = 1
@@ -171,8 +171,9 @@
P.remove_from_storage(MC)
qdel(MC)
if(loaded)
- to_chat(user, "You fill [src] with the monkey cubes stored in [O]. [src] now has [monkeys] monkey cubes stored.")
- return
+ to_chat(user, "You fill [src] with the monkey cubes stored in [used]. [src] now has [monkeys] monkey cubes stored.")
+ return ITEM_INTERACT_COMPLETE
+
return ..()
/obj/machinery/computer/camera_advanced/xenobio/multitool_act(mob/user, obj/item/I)
diff --git a/code/modules/ruins/objects_and_mobs/id_upgrader.dm b/code/modules/ruins/objects_and_mobs/id_upgrader.dm
index af4fa2906ba8..3e83f63434f2 100644
--- a/code/modules/ruins/objects_and_mobs/id_upgrader.dm
+++ b/code/modules/ruins/objects_and_mobs/id_upgrader.dm
@@ -8,12 +8,12 @@
/// Have we been used?
var/used = FALSE
-/obj/machinery/computer/id_upgrader/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/card/id))
- var/obj/item/card/id/D = I
+/obj/machinery/computer/id_upgrader/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/card/id))
+ var/obj/item/card/id/D = used
if(!length(access_to_give))
to_chat(user, "This machine appears to be configured incorrectly.")
- return
+ return ITEM_INTERACT_COMPLETE
var/did_upgrade = FALSE
var/list/id_access = D.GetAccess()
@@ -29,6 +29,6 @@
else
to_chat(user, "Your ID card already has all the access this machine can give.")
- return
+ return ITEM_INTERACT_COMPLETE
return ..()
diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm
index 2a761a0ea1f5..d2c8a3901edc 100644
--- a/code/modules/security_levels/keycard_authentication.dm
+++ b/code/modules/security_levels/keycard_authentication.dm
@@ -43,34 +43,35 @@
to_chat(user, "The station AI is not to interact with these devices.")
return
-/obj/machinery/keycard_auth/attackby__legacy__attackchain(obj/item/W, mob/user, params)
+/obj/machinery/keycard_auth/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(stat & (NOPOWER|BROKEN))
to_chat(user, "This device is not powered.")
- return
- if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))
- if(!check_access(W))
+ return ITEM_INTERACT_COMPLETE
+ if(istype(used, /obj/item/card/id) || istype(used, /obj/item/pda))
+ if(!check_access(used))
to_chat(user, "Access denied.")
- return
+ return ITEM_INTERACT_COMPLETE
if(user == event_source?.triggered_by)
to_chat(user, "Identical body-signature detected. Access denied.")
- return
+ return ITEM_INTERACT_COMPLETE
if(active)
//This is not the device that made the initial request. It is the device confirming the request.
if(!event_source)
- return
+ return ITEM_INTERACT_COMPLETE
event_source.confirmed_by = user
SStgui.update_uis(event_source)
SStgui.update_uis(src)
event_source.confirm_and_trigger()
reset()
- return
+ return ITEM_INTERACT_COMPLETE
if(swiping)
if(event == "Emergency Response Team" && !ert_reason)
to_chat(user, "Supply a reason for calling the ERT first!")
- return
+ return ITEM_INTERACT_COMPLETE
triggered_by = user
SStgui.update_uis(src)
broadcast_request() //This is the device making the initial event request. It needs to broadcast to other devices
+
return ..()
/obj/machinery/keycard_auth/power_change()
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 8c41e1778169..31b9cfff3d03 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -36,93 +36,103 @@
if(hijack_announce)
. += "It is probably best to fortify your position as to be uninterrupted during the attempt, given the automatic announcements..."
-/obj/machinery/computer/emergency_shuttle/attackby__legacy__attackchain(obj/item/card/id/W, mob/user, params)
+/obj/machinery/computer/emergency_shuttle/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(stat & (BROKEN|NOPOWER))
return
- if(!istype(W, /obj/item/card/id))
+
+ var/obj/item/card/id/id_card
+ if(istype(used, /obj/item/card/id))
+ id_card = used
+ else if(istype(used, /obj/item/pda))
+ var/obj/item/pda/pda = used
+ id_card = pda.id
+ else
return
+
if(SSshuttle.emergency.mode != SHUTTLE_DOCKED && !SSshuttle.emergency.aihacked)
return
if(!user)
return
if(SSshuttle.emergency.timeLeft() < 11)
return
- if(istype(W, /obj/item/card/id)||istype(W, /obj/item/pda))
- if(istype(W, /obj/item/pda))
- var/obj/item/pda/pda = W
- W = pda.id
- if(!W.access) //no access
- to_chat(user, "The access level of [W.registered_name]\'s card is not high enough. ")
- return
- var/list/cardaccess = W.access
- if(!istype(cardaccess, /list) || !length(cardaccess)) //no access
- to_chat(user, "The access level of [W.registered_name]\'s card is not high enough. ")
- return
+ if(!id_card.access) //no access
+ to_chat(user, "The access level of [id_card.registered_name]\'s card is not high enough. ")
+ return ITEM_INTERACT_COMPLETE
+
+ var/list/cardaccess = id_card.access
+ if(!istype(cardaccess, /list) || !length(cardaccess)) //no access
+ to_chat(user, "The access level of [id_card.registered_name]\'s card is not high enough. ")
+ return ITEM_INTERACT_COMPLETE
+
+ if(!(ACCESS_HEADS in id_card.access)) //doesn't have this access
+ to_chat(user, "The access level of [id_card.registered_name]\'s card is not high enough. ")
+ return ITEM_INTERACT_COMPLETE
+ if(!SSshuttle.emergency.aihacked)
+ var/choice = tgui_alert(user, "Would you like to (un)authorize a shortened launch time? [auth_need - length(authorized)] authorization\s are still needed. Use abort to cancel all authorizations.", "Shuttle Launch", list("Authorize", "Repeal", "Abort"))
+ if(SSshuttle.emergency.mode != SHUTTLE_DOCKED || user.get_active_hand() != id_card)
+ return ITEM_INTERACT_COMPLETE
+
+ var/seconds = SSshuttle.emergency.timeLeft()
+ if(seconds <= 10)
+ return ITEM_INTERACT_COMPLETE
- if(!(ACCESS_HEADS in W.access)) //doesn't have this access
- to_chat(user, "The access level of [W.registered_name]\'s card is not high enough. ")
- return 0
- if(!SSshuttle.emergency.aihacked)
- var/choice = tgui_alert(user, "Would you like to (un)authorize a shortened launch time? [auth_need - length(authorized)] authorization\s are still needed. Use abort to cancel all authorizations.", "Shuttle Launch", list("Authorize", "Repeal", "Abort"))
- if(SSshuttle.emergency.mode != SHUTTLE_DOCKED || user.get_active_hand() != W)
- return 0
-
- var/seconds = SSshuttle.emergency.timeLeft()
- if(seconds <= 10)
- return 0
-
- switch(choice)
- if("Authorize")
- if(!authorized.Find(W.registered_name))
- authorized += W.registered_name
- if(auth_need - length(authorized) > 0)
- message_admins("[key_name_admin(user)] has authorized early shuttle launch.")
- log_game("[key_name(user)] has authorized early shuttle launch in ([x], [y], [z]).")
- GLOB.minor_announcement.Announce("[auth_need - length(authorized)] more authorization(s) needed until shuttle is launched early")
- else
- message_admins("[key_name_admin(user)] has launched the emergency shuttle [seconds] seconds before launch.")
- log_game("[key_name(user)] has launched the emergency shuttle in ([x], [y], [z]) [seconds] seconds before launch.")
- GLOB.minor_announcement.Announce("The emergency shuttle will launch in 10 seconds")
- SSshuttle.emergency.setTimer(10 SECONDS)
-
- if("Repeal")
- if(authorized.Remove(W.registered_name))
- GLOB.minor_announcement.Announce("[auth_need - length(authorized)] authorizations needed until shuttle is launched early")
-
- if("Abort")
- if(length(authorized))
- GLOB.minor_announcement.Announce("All authorizations to launch the shuttle early have been revoked.")
- authorized.Cut()
- return FALSE
- var/choice = tgui_alert(user, "\[ERROR] HOSTILE AI DETECTED IN SHUTTLE CONTROL. RESTORE SHUTTLE CONSOLE TO BACKUP SYSTEM? [auth_need - length(authorized)] AUTHORIZATIONS\s REQUIRED TO RESTORE. ABORT TO REMOVE ALL AUTHORIZATION OF BACKUP RESTORAL, P-P--PLEASE...", "HOSTILE VIRAL AI INTRUSION", list("Authorize", "Repeal", "Abort"))
- if(user.get_active_hand() != W)
- return FALSE
switch(choice)
if("Authorize")
- if(!authorized.Find(W.registered_name))
- authorized += W.registered_name
+ if(!authorized.Find(id_card.registered_name))
+ authorized += id_card.registered_name
if(auth_need - length(authorized) > 0)
- message_admins("[key_name_admin(user)] has authorized restoring shuttle AI backup.")
- log_game("[key_name(user)] has authorized restoring shuttle AI backup in ([x], [y], [z]).")
- GLOB.minor_announcement.Announce("[auth_need - length(authorized)] more authorization(s) needed until sh-tt- STOP STOP STOP STOP!")
+ message_admins("[key_name_admin(user)] has authorized early shuttle launch.")
+ log_game("[key_name(user)] has authorized early shuttle launch in ([x], [y], [z]).")
+ GLOB.minor_announcement.Announce("[auth_need - length(authorized)] more authorization(s) needed until shuttle is launched early")
else
- message_admins("[key_name_admin(user)] has wiped the AI in the shuttle computer.")
- log_game("[key_name(user)] has wiped the AI in the shuttle computer in ([x], [y], [z])")
- GLOB.minor_announcement.Announce("NO NO NO N---\[[Gibberish("###########", 100, 90)]\]...")
- GLOB.minor_announcement.Announce("Shuttle AI restored to emergency backup. Avoiding toll hyperlanes. Recalculating route. Recalculating. Recalculating. Please stand by...")
- SSshuttle.emergency.setTimer(60 SECONDS)
- kill_the_ai()
+ message_admins("[key_name_admin(user)] has launched the emergency shuttle [seconds] seconds before launch.")
+ log_game("[key_name(user)] has launched the emergency shuttle in ([x], [y], [z]) [seconds] seconds before launch.")
+ GLOB.minor_announcement.Announce("The emergency shuttle will launch in 10 seconds")
+ SSshuttle.emergency.setTimer(10 SECONDS)
if("Repeal")
- if(authorized.Remove(W.registered_name))
- GLOB.minor_announcement.Announce("[auth_need - length(authorized)] authorizations needed unti- THE SHUTTLE EXPLODES. PLEASE REVO-KE ALL AUTHORIZATIONS.")
+ if(authorized.Remove(id_card.registered_name))
+ GLOB.minor_announcement.Announce("[auth_need - length(authorized)] authorizations needed until shuttle is launched early")
if("Abort")
if(length(authorized))
- GLOB.minor_announcement.Announce("All authorizations to restore shuttle AI backup have been re-- Really applied. The AI is gone. There is no reason to worry. Enjoy your flight.")
+ GLOB.minor_announcement.Announce("All authorizations to launch the shuttle early have been revoked.")
authorized.Cut()
+ return ITEM_INTERACT_COMPLETE
+
+ var/choice = tgui_alert(user, "\[ERROR] HOSTILE AI DETECTED IN SHUTTLE CONTROL. RESTORE SHUTTLE CONSOLE TO BACKUP SYSTEM? [auth_need - length(authorized)] AUTHORIZATIONS\s REQUIRED TO RESTORE. ABORT TO REMOVE ALL AUTHORIZATION OF BACKUP RESTORAL, P-P--PLEASE...", "HOSTILE VIRAL AI INTRUSION", list("Authorize", "Repeal", "Abort"))
+ if(user.get_active_hand() != id_card)
+ return ITEM_INTERACT_COMPLETE
+
+ switch(choice)
+ if("Authorize")
+ if(!authorized.Find(id_card.registered_name))
+ authorized += id_card.registered_name
+ if(auth_need - length(authorized) > 0)
+ message_admins("[key_name_admin(user)] has authorized restoring shuttle AI backup.")
+ log_game("[key_name(user)] has authorized restoring shuttle AI backup in ([x], [y], [z]).")
+ GLOB.minor_announcement.Announce("[auth_need - length(authorized)] more authorization(s) needed until sh-tt- STOP STOP STOP STOP!")
+ else
+ message_admins("[key_name_admin(user)] has wiped the AI in the shuttle computer.")
+ log_game("[key_name(user)] has wiped the AI in the shuttle computer in ([x], [y], [z])")
+ GLOB.minor_announcement.Announce("NO NO NO N---\[[Gibberish("###########", 100, 90)]\]...")
+ GLOB.minor_announcement.Announce("Shuttle AI restored to emergency backup. Avoiding toll hyperlanes. Recalculating route. Recalculating. Recalculating. Please stand by...")
+ SSshuttle.emergency.setTimer(60 SECONDS)
+ kill_the_ai()
+
+ if("Repeal")
+ if(authorized.Remove(id_card.registered_name))
+ GLOB.minor_announcement.Announce("[auth_need - length(authorized)] authorizations needed unti- THE SHUTTLE EXPLODES. PLEASE REVO-KE ALL AUTHORIZATIONS.")
+
+ if("Abort")
+ if(length(authorized))
+ GLOB.minor_announcement.Announce("All authorizations to restore shuttle AI backup have been re-- Really applied. The AI is gone. There is no reason to worry. Enjoy your flight.")
+ authorized.Cut()
+
+ return ITEM_INTERACT_COMPLETE
+
/obj/machinery/computer/emergency_shuttle/emag_act(mob/user)
if(!emagged && SSshuttle.emergency.mode == SHUTTLE_DOCKED)
var/time = SSshuttle.emergency.timeLeft()
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
index 5e6477acf1d1..0f2627476bee 100644
--- a/code/modules/station_goals/dna_vault.dm
+++ b/code/modules/station_goals/dna_vault.dm
@@ -252,9 +252,9 @@ GLOBAL_LIST_INIT(non_simple_animals, typecacheof(list(/mob/living/carbon/human/m
if(length(plants) >= plants_max && length(animals) >= animals_max && length(dna) >= dna_max)
completed = TRUE
-/obj/machinery/dna_vault/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/dna_probe))
- var/obj/item/dna_probe/P = I
+/obj/machinery/dna_vault/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/dna_probe))
+ var/obj/item/dna_probe/P = used
var/uploaded = 0
for(var/plant in P.plants)
if(!plants[plant])
@@ -270,8 +270,9 @@ GLOBAL_LIST_INIT(non_simple_animals, typecacheof(list(/mob/living/carbon/human/m
dna[ui] = 1
check_goal()
to_chat(user, "[uploaded] new datapoints uploaded.")
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/dna_vault/proc/upgrade(mob/living/carbon/human/H, upgrade_type)
if(!(upgrade_type in power_lottery[H]))
diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm
index 5165a186b387..b4cf11f17c3b 100644
--- a/code/modules/station_goals/shield.dm
+++ b/code/modules/station_goals/shield.dm
@@ -250,11 +250,8 @@
/obj/machinery/satellite/update_icon_state()
icon_state = active ? "sat_active" : "sat_inactive"
-/obj/machinery/satellite/attackby__legacy__attackchain(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/multitool))
- to_chat(user, "// NTSAT-[id] // Mode : [active ? "PRIMARY" : "STANDBY"] //[emagged ? "DEBUG_MODE //" : ""]")
- else
- return ..()
+/obj/machinery/satellite/multitool_act(mob/living/user, obj/item/I)
+ to_chat(user, "// NTSAT-[id] // Mode : [active ? "PRIMARY" : "STANDBY"] //[emagged ? "DEBUG_MODE //" : ""]")
/obj/machinery/satellite/meteor_shield
name = "Meteor Shield Satellite"
diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm
index 587054430860..3249f197860b 100644
--- a/code/modules/telesci/telesci_computer.dm
+++ b/code/modules/telesci/telesci_computer.dm
@@ -60,27 +60,29 @@
. = ..()
. += "There are [crystals ? crystals : "no"] bluespace crystal\s in the crystal slots."
-/obj/machinery/computer/telescience/attackby__legacy__attackchain(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/stack/ore/bluespace_crystal))
- var/obj/item/stack/ore/bluespace_crystal/B = W
+/obj/machinery/computer/telescience/item_interaction(mob/living/user, obj/item/used, list/modifiers)
+ if(istype(used, /obj/item/stack/ore/bluespace_crystal))
+ var/obj/item/stack/ore/bluespace_crystal/B = used
if(crystals >= MAX_CRYSTALS)
to_chat(user, "There are not enough crystal slots.")
- return
-
+ return ITEM_INTERACT_COMPLETE
crystals += 1
user.visible_message("[user] inserts a [B.singular_name] into [src]'s crystal slot.")
B.use(1)
SStgui.update_uis(src)
-
- else if(istype(W, /obj/item/gps))
+ return ITEM_INTERACT_COMPLETE
+ else if(istype(used, /obj/item/gps))
+ // TODO: Provide some kind of message if there's already an inserted GPS.
+ // For now, just do nothing.
if(!inserted_gps)
- inserted_gps = W
- user.transfer_item_to(W, src)
- user.visible_message("[user] inserts [W] into [src]'s GPS device slot.")
+ inserted_gps = used
+ user.transfer_item_to(used, src)
+ user.visible_message("[user] inserts [used] into [src]'s GPS device slot.")
SStgui.update_uis(src)
- else
- return ..()
+ return ITEM_INTERACT_COMPLETE
+
+ return ..()
/obj/machinery/computer/telescience/multitool_act(mob/living/user, obj/item/I)
diff --git a/code/tests/_game_test.dm b/code/tests/_game_test.dm
index 32c2c3bc661e..e94e10d85e65 100644
--- a/code/tests/_game_test.dm
+++ b/code/tests/_game_test.dm
@@ -15,6 +15,8 @@ GLOBAL_LIST_EMPTY(game_test_chats)
/// Asserts that a parameter is null
#define TEST_ASSERT_NULL(a, reason) if(!isnull(a)) { return Fail("Expected null value but received [a]: [reason || "No reason"]", __FILE__, __LINE__) }
+#define TEST_ASSERT_LAST_CHATLOG(puppet, text) if(!puppet.last_chatlog_has_text(text)) { return Fail("Expected `[text]` in last chatlog but got `[puppet.get_last_chatlog()]`", __FILE__, __LINE__) }
+
/// Asserts that the two parameters passed are equal, fails otherwise
/// Optionally allows an additional message in the case of a failure
#define TEST_ASSERT_EQUAL(a, b, message) do { \
@@ -49,12 +51,15 @@ GLOBAL_LIST_EMPTY(game_test_chats)
var/list/procs_tested
//usable vars
- var/static/list/available_turfs
+ var/list/available_turfs
//internal shit
var/succeeded = TRUE
var/list/allocated
var/list/fail_reasons
+ var/testing_area_name = "test_generic.dmm"
+ var/obj/effect/landmark/bottom_left
+ var/obj/effect/landmark/top_right
/datum/game_test/New()
if(!length(available_turfs))
@@ -66,7 +71,7 @@ GLOBAL_LIST_EMPTY(game_test_chats)
if(!length(testing_levels))
Fail("Could not find appropriate z-level for spawning test areas")
var/testing_z_level = pick(testing_levels)
- var/datum/map_template/generic_test_area = GLOB.map_templates["test_generic.dmm"]
+ var/datum/map_template/generic_test_area = GLOB.map_templates[testing_area_name]
if(!generic_test_area.load(locate(TRANSITIONEDGE + 1, TRANSITIONEDGE + 1, testing_z_level)))
Fail("Could not place generic testing area on z-level [testing_z_level]")
@@ -76,6 +81,12 @@ GLOBAL_LIST_EMPTY(game_test_chats)
for(var/turf/T in get_area_turfs(/area/game_test))
for(var/atom/movable/AM in T)
qdel(AM)
+
+ // Gotta destroy these landmarks so the next test
+ // doesn't end up seeing them if it tries to load a new map
+ qdel(bottom_left)
+ qdel(top_right)
+
return ..()
/datum/game_test/proc/Run()
@@ -91,8 +102,6 @@ GLOBAL_LIST_EMPTY(game_test_chats)
/datum/game_test/proc/get_test_turfs()
var/list/result = list()
- var/obj/effect/landmark/bottom_left
- var/obj/effect/landmark/top_right
for(var/obj/effect/landmark in GLOB.landmarks_list)
if(istype(landmark, /obj/effect/landmark/game_test/bottom_left_corner))
bottom_left = landmark
diff --git a/code/tests/_game_test_puppeteer.dm b/code/tests/_game_test_puppeteer.dm
index 10e39706602e..9d56066a4073 100644
--- a/code/tests/_game_test_puppeteer.dm
+++ b/code/tests/_game_test_puppeteer.dm
@@ -50,12 +50,13 @@
/datum/test_puppeteer/proc/click_on(target, params)
var/datum/test_puppeteer/puppet_target = target
- sleep(max(puppet.next_click, puppet.next_move) - world.time + 1)
if(istype(puppet_target))
puppet.ClickOn(puppet_target.puppet, params)
return
puppet.ClickOn(target, params)
+ puppet.next_click = world.time
+ puppet.next_move = world.time
/datum/test_puppeteer/proc/spawn_mob_nearby(mob_type)
for(var/turf/T in RANGE_TURFS(1, puppet))
@@ -65,12 +66,13 @@
/datum/test_puppeteer/proc/change_turf_nearby(turf_type, direction = -1)
var/turf/T
+ var/turf/center = get_turf(puppet)
if(direction >= 0)
T = get_step(puppet, direction)
else
// just check for any contents, not blocked_turf which includes turf density
// (which we don't really care about)
- for(var/turf/nearby in RANGE_TURFS(1, puppet))
+ for(var/turf/nearby in RANGE_TURFS(1, center))
if(!length(nearby.contents))
T = nearby
@@ -91,9 +93,39 @@
/datum/test_puppeteer/proc/rejuvenate()
puppet.rejuvenate()
-/datum/test_puppeteer/proc/last_chatlog_has_text(snippet)
+/datum/test_puppeteer/proc/get_last_chatlog()
if(!(puppet.mind.key in GLOB.game_test_chats))
return FALSE
var/list/puppet_chat_list = GLOB.game_test_chats[puppet.mind.key]
- var/last_chat_html = puppet_chat_list[length(puppet_chat_list)]
- return findtextEx(last_chat_html, snippet)
+ return puppet_chat_list[length(puppet_chat_list)]
+
+/datum/test_puppeteer/proc/last_chatlog_has_text(snippet)
+ return findtextEx(get_last_chatlog(), snippet)
+
+/datum/test_puppeteer/proc/find_nearby(atom_type)
+ for(var/turf/T in RANGE_TURFS(1, puppet))
+ for(var/atom/A in T.contents)
+ if(istype(A, atom_type))
+ return A
+
+// No we don't technically need to put these things into an actual backpack and
+// so forth, we could just leave them lying around and teleport them to the
+// player but this keeps things realistic and may surface issues we wouldn't
+// think to test for.
+/datum/test_puppeteer/proc/put_away(obj/object)
+ if(!puppet.back)
+ puppet.equip_to_appropriate_slot(new/obj/item/storage/backpack)
+
+ var/obj/item/storage/backpack = puppet.back
+ backpack.handle_item_insertion(object, puppet)
+
+/datum/test_puppeteer/proc/retrieve(obj/object)
+ if(!puppet.back)
+ return
+
+ var/obj/item/storage/backpack = puppet.back
+ if(!(object in backpack.contents))
+ return
+
+ backpack.remove_item_from_storage(object)
+ puppet.put_in_active_hand(object)
diff --git a/code/tests/attack_chain/test_attack_chain_machinery.dm b/code/tests/attack_chain/test_attack_chain_machinery.dm
new file mode 100644
index 000000000000..873dc14b614a
--- /dev/null
+++ b/code/tests/attack_chain/test_attack_chain_machinery.dm
@@ -0,0 +1,160 @@
+/datum/game_test/attack_chain_machinery
+ testing_area_name = "test_attack_chain_machinery.dmm"
+ var/list/machine_instances_by_type = list()
+
+/datum/game_test/attack_chain_machinery/proc/teleport_to_first(datum/test_puppeteer/player, obj_type, dir=EAST)
+ if(length(machine_instances_by_type[obj_type]))
+ var/machine = machine_instances_by_type[obj_type][1]
+ player.puppet.forceMove(get_step(machine, dir))
+ return machine
+ TEST_FAIL("could not find [obj_type] to teleport puppet to")
+
+/datum/game_test/attack_chain_machinery/New()
+ . = ..()
+ for(var/turf/T in available_turfs)
+ for(var/obj/machinery/machine in T)
+ LAZYOR(machine_instances_by_type[machine.type], machine)
+
+/datum/game_test/attack_chain_machinery/Run()
+ var/datum/test_puppeteer/player = new(src)
+
+ // Here we fucking go. There's a lot of machines and interactions to test
+ // here. The basic plan is to test one or two things within the subtype
+ // interaction, And then test one or two things that should be handled by
+ // the parent And possibly combat attacks if necessary.
+
+ // DNA Scanner
+ var/obj/scanner = teleport_to_first(player, /obj/machinery/dna_scannernew)
+ var/area/admin_area = get_area(player.puppet)
+ player.spawn_obj_in_hand(/obj/item/reagent_containers/glass/beaker)
+ player.click_on(scanner)
+ TEST_ASSERT_LAST_CHATLOG(player, "You add a beaker")
+ var/obj/screwdriver = player.spawn_obj_in_hand(/obj/item/screwdriver)
+ player.click_on(scanner)
+ TEST_ASSERT_LAST_CHATLOG(player, "You open the maintenance hatch")
+ player.put_away(screwdriver)
+
+ // Abductor console
+ var/obj/abductor_console = teleport_to_first(player, /obj/machinery/abductor/console)
+ var/obj/gizmo = player.spawn_obj_in_hand(/obj/item/abductor/gizmo)
+ player.click_on(abductor_console)
+ TEST_ASSERT_LAST_CHATLOG(player, "You link the tool")
+ qdel(gizmo)
+ var/obj/welder = player.spawn_obj_in_hand(/obj/item/weldingtool)
+ player.set_intent("harm")
+ player.click_on(abductor_console)
+ TEST_ASSERT_LAST_CHATLOG(player, "You hit Abductor console with the welding tool!")
+ player.set_intent("help")
+ player.put_away(welder)
+
+ // Abductor replacement organ storage
+ var/obj/machinery/abductor/gland_dispenser/dispenser = teleport_to_first(player, /obj/machinery/abductor/gland_dispenser)
+ var/obj/gland = player.spawn_obj_in_hand(/obj/item/organ/internal/heart/gland)
+ player.click_on(dispenser)
+ TEST_ASSERT(gland in dispenser.contents, "did not place gland in dispenser")
+
+ // Autolathe
+ var/obj/machinery/autolathe/autolathe = teleport_to_first(player, /obj/machinery/autolathe)
+ autolathe.disk_design_load_delay = 0
+ var/obj/design_disk = player.spawn_obj_in_hand(/obj/item/disk/design_disk/golem_shell)
+ player.click_on(autolathe)
+ TEST_ASSERT_LAST_CHATLOG(player, "You begin to load a design")
+ qdel(design_disk)
+ player.retrieve(screwdriver)
+ player.click_on(autolathe)
+ TEST_ASSERT_LAST_CHATLOG(player, "You open the maintenance hatch")
+ player.put_away(screwdriver)
+ var/obj/rped = player.spawn_obj_in_hand(/obj/item/storage/part_replacer/tier4)
+ player.click_on(autolathe)
+ TEST_ASSERT_LAST_CHATLOG(player, "micro-manipulator replaced with femto-manipulator")
+ qdel(rped)
+
+ var/obj/machinery/nuclearbomb/nuke = teleport_to_first(player, /obj/machinery/nuclearbomb/undeployed)
+ var/obj/disk = player.spawn_obj_in_hand(/obj/item/disk/nuclear/unrestricted)
+ player.click_on(nuke)
+ TEST_ASSERT_LAST_CHATLOG(player, "You need to deploy")
+ nuke.extended = TRUE
+ player.click_on(nuke)
+ TEST_ASSERT(disk in nuke.contents, "Disk not inserted into nuke")
+ player.retrieve(screwdriver)
+ player.click_on(nuke)
+ TEST_ASSERT_LAST_CHATLOG(player, "You unscrew the control panel")
+ player.put_away(screwdriver)
+
+ var/obj/camera = teleport_to_first(player, /obj/machinery/camera)
+ player.retrieve(screwdriver)
+ player.click_on(camera) // with screwdriver
+ TEST_ASSERT_LAST_CHATLOG(player, "panel open")
+ player.put_away(screwdriver)
+ player.spawn_obj_in_hand(/obj/item/stack/sheet/mineral/plasma)
+ player.click_on(camera)
+ TEST_ASSERT_LAST_CHATLOG(player, "You attach the solid plasma")
+ var/obj/knife = player.spawn_obj_in_hand(/obj/item/kitchen/knife)
+ player.set_intent("harm")
+ player.click_on(camera)
+ TEST_ASSERT_LAST_CHATLOG(player, "You hit the security camera with the kitchen knife")
+ player.set_intent("help")
+ player.put_away(knife)
+
+ var/obj/chem_dispenser = teleport_to_first(player, /obj/machinery/chem_dispenser)
+ player.retrieve(screwdriver)
+ player.click_on(chem_dispenser)
+ TEST_ASSERT_LAST_CHATLOG(player, "You open the maintenance hatch")
+ player.puppet.swap_hand()
+ player.spawn_obj_in_hand(/obj/item/reagent_containers/glass/beaker)
+ player.click_on(chem_dispenser)
+ TEST_ASSERT_LAST_CHATLOG(player, "Close the maintenance panel first")
+ player.puppet.swap_hand()
+ player.click_on(chem_dispenser)
+ player.puppet.swap_hand()
+ player.click_on(chem_dispenser)
+ TEST_ASSERT_LAST_CHATLOG(player, "You set the beaker on the machine")
+ player.put_away(screwdriver)
+
+ var/obj/upload_console = teleport_to_first(player, /obj/machinery/computer/aiupload)
+ var/obj/ai_module = player.spawn_obj_in_hand(/obj/item/ai_module/asimov)
+ player.click_on(upload_console)
+ TEST_ASSERT_LAST_CHATLOG(player, "No AI selected")
+ qdel(ai_module)
+ player.retrieve(knife)
+ player.set_intent("harm")
+ player.click_on(upload_console)
+ TEST_ASSERT_LAST_CHATLOG(player, "AI upload console with the kitchen knife")
+ player.put_away(knife)
+
+ var/obj/machinery/cell_charger/cell_charger = teleport_to_first(player, /obj/machinery/cell_charger)
+ var/obj/cell = player.spawn_obj_in_hand(/obj/item/stock_parts/cell)
+ player.click_on(cell_charger)
+ TEST_ASSERT_LAST_CHATLOG(player, "You insert a cell into the charger")
+ var/obj/cell2 = player.spawn_obj_in_hand(/obj/item/stock_parts/cell)
+ player.click_on(cell_charger)
+ TEST_ASSERT_LAST_CHATLOG(player, "already a cell in the charger")
+ qdel(cell2)
+ player.click_on(cell_charger)
+ TEST_ASSERT_NULL(cell_charger.charging, "cell charger still charging")
+ qdel(cell)
+ player.retrieve(screwdriver)
+ player.click_on(cell_charger)
+ player.put_away(screwdriver)
+ rped = player.spawn_obj_in_hand(/obj/item/storage/part_replacer/tier4)
+ player.click_on(cell_charger)
+ TEST_ASSERT_LAST_CHATLOG(player, "replaced with quadratic capacitor")
+ qdel(rped)
+
+ player.puppet.forceMove(top_right.loc)
+ var/turf/wall = player.change_turf_nearby(/turf/simulated/wall, EAST)
+ player.spawn_obj_in_hand(/obj/item/mounted/frame/firealarm)
+ admin_area.requires_power = TRUE
+ player.click_on(wall)
+ admin_area.requires_power = FALSE
+ player.spawn_obj_in_hand(/obj/item/firealarm_electronics)
+ var/obj/firealarm_frame = player.find_nearby(/obj/machinery/firealarm)
+ player.click_on(firealarm_frame)
+ TEST_ASSERT_LAST_CHATLOG(player, "You insert the circuit")
+ var/obj/cables = player.spawn_obj_in_hand(/obj/item/stack/cable_coil/ten)
+ player.click_on(firealarm_frame)
+ TEST_ASSERT_LAST_CHATLOG(player, "You wire")
+ qdel(cables)
+ player.retrieve(screwdriver)
+ player.click_on(firealarm_frame)
+ TEST_ASSERT_LAST_CHATLOG(player, "You close the panel")
diff --git a/code/tests/game_tests.dm b/code/tests/game_tests.dm
index 0bbe3fff14c8..d482918253ff 100644
--- a/code/tests/game_tests.dm
+++ b/code/tests/game_tests.dm
@@ -6,6 +6,7 @@
#include "_game_test.dm"
#include "atmos\test_ventcrawl.dm"
#include "attack_chain\test_attack_chain_cult_dagger.dm"
+#include "attack_chain\test_attack_chain_machinery.dm"
#include "attack_chain\test_attack_chain_turf.dm"
#include "attack_chain\test_attack_chain_vehicles.dm"
#include "games\test_cards.dm"