diff --git a/_maps/map_files/tests/test_attack_chain_structures.dmm b/_maps/map_files/tests/test_attack_chain_structures.dmm new file mode 100644 index 00000000000..fc050ce0ca9 --- /dev/null +++ b/_maps/map_files/tests/test_attack_chain_structures.dmm @@ -0,0 +1,606 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aG" = ( +/obj/structure/machine_frame, +/turf/simulated/floor/plasteel, +/area/game_test) +"bw" = ( +/obj/structure/extinguisher_cabinet, +/turf/simulated/wall/r_wall, +/area/game_test) +"cf" = ( +/obj/structure/fermenting_barrel, +/turf/simulated/floor/plasteel, +/area/game_test) +"cH" = ( +/obj/structure/grille, +/turf/simulated/floor/plasteel, +/area/game_test) +"dG" = ( +/obj/structure/holosign/barrier/atmos, +/turf/simulated/floor/plasteel, +/area/game_test) +"eN" = ( +/obj/structure/mineral_door/iron, +/turf/simulated/floor/plasteel, +/area/game_test) +"eY" = ( +/obj/structure/mirror/magic{ + pixel_y = 32 + }, +/turf/simulated/floor/plasteel, +/area/game_test) +"fA" = ( +/obj/structure/closet/crate/secure/loot, +/turf/simulated/floor/plasteel, +/area/game_test) +"jj" = ( +/obj/structure/rack, +/turf/simulated/floor/plasteel, +/area/game_test) +"kg" = ( +/obj/structure/windoor_assembly, +/turf/simulated/floor/plasteel, +/area/game_test) +"kT" = ( +/obj/structure/girder/cult, +/turf/simulated/floor/plasteel, +/area/game_test) +"le" = ( +/obj/structure/noticeboard, +/turf/simulated/wall/r_wall, +/area/game_test) +"lH" = ( +/obj/structure/barricade/wooden, +/turf/simulated/floor/plasteel, +/area/game_test) +"ms" = ( +/obj/structure/beebox, +/turf/simulated/floor/plasteel, +/area/game_test) +"nj" = ( +/obj/structure/particle_accelerator/fuel_chamber, +/turf/simulated/floor/plasteel, +/area/game_test) +"nK" = ( +/obj/structure/cult/functional/forge, +/turf/simulated/floor/plasteel, +/area/game_test) +"pS" = ( +/obj/structure/target_stake, +/turf/simulated/floor/plasteel, +/area/game_test) +"qt" = ( +/obj/structure/constructshell, +/turf/simulated/floor/plasteel, +/area/game_test) +"rT" = ( +/turf/simulated/floor/plasteel, +/area/game_test) +"sE" = ( +/obj/structure/chair, +/turf/simulated/floor/plasteel, +/area/game_test) +"sR" = ( +/obj/structure/displaycase, +/turf/simulated/floor/plasteel, +/area/game_test) +"tn" = ( +/obj/structure/flora/ash, +/turf/simulated/floor/plasteel, +/area/game_test) +"tQ" = ( +/obj/structure/guillotine, +/turf/simulated/floor/plasteel, +/area/game_test) +"ve" = ( +/obj/structure/computerframe, +/turf/simulated/floor/plasteel, +/area/game_test) +"wb" = ( +/obj/structure/table_frame, +/turf/simulated/floor/plasteel, +/area/game_test) +"wn" = ( +/obj/effect/spawner/window, +/turf/simulated/floor/plasteel, +/area/game_test) +"wr" = ( +/obj/structure/inflatable, +/turf/simulated/floor/plasteel, +/area/game_test) +"yd" = ( +/obj/structure/bed/roller, +/turf/simulated/floor/plasteel, +/area/game_test) +"yn" = ( +/obj/structure/big_delivery, +/turf/simulated/floor/plasteel, +/area/game_test) +"zK" = ( +/obj/structure/reagent_dispensers/water_cooler, +/turf/simulated/floor/plasteel, +/area/game_test) +"AG" = ( +/obj/structure/door_assembly, +/turf/simulated/floor/plasteel, +/area/game_test) +"AI" = ( +/obj/structure/table, +/turf/simulated/floor/plasteel, +/area/game_test) +"BX" = ( +/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) +"Cd" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/simulated/floor/plating, +/area/game_test) +"DQ" = ( +/obj/structure/morgue, +/turf/simulated/floor/plasteel, +/area/game_test) +"FH" = ( +/obj/structure/snowman/built, +/turf/simulated/floor/plasteel, +/area/game_test) +"FZ" = ( +/obj/structure/largecrate, +/turf/simulated/floor/plasteel, +/area/game_test) +"GO" = ( +/obj/structure/reflector, +/turf/simulated/floor/plasteel, +/area/game_test) +"JP" = ( +/obj/structure/statue/gold/hop, +/turf/simulated/floor/plasteel, +/area/game_test) +"NN" = ( +/obj/structure/kitchenspike_frame, +/turf/simulated/floor/plasteel, +/area/game_test) +"Od" = ( +/turf/simulated/wall/r_wall, +/area/game_test) +"OE" = ( +/obj/structure/ai_core, +/turf/simulated/floor/plasteel, +/area/game_test) +"QL" = ( +/obj/structure/disposalconstruct, +/turf/simulated/floor/plating, +/area/game_test) +"RH" = ( +/obj/structure/filingcabinet, +/turf/simulated/floor/plasteel, +/area/game_test) +"RN" = ( +/obj/structure/firelock_frame, +/turf/simulated/floor/plasteel, +/area/game_test) +"Sw" = ( +/obj/effect/landmark/game_test/top_right_corner, +/turf/simulated/floor/plasteel, +/area/game_test) +"Uu" = ( +/obj/structure/ore_box, +/turf/simulated/floor/plasteel, +/area/game_test) +"UT" = ( +/obj/structure/shelf, +/turf/simulated/floor/plasteel, +/area/game_test) +"VM" = ( +/obj/structure/loom, +/turf/simulated/floor/plasteel, +/area/game_test) +"Wr" = ( +/obj/structure/lattice, +/turf/space, +/area/game_test) +"Xt" = ( +/obj/structure/girder, +/turf/simulated/floor/plasteel, +/area/game_test) +"Ye" = ( +/obj/structure/kitchenspike, +/turf/simulated/floor/plasteel, +/area/game_test) +"YV" = ( +/obj/structure/clockwork/wall_gear, +/turf/simulated/floor/plasteel, +/area/game_test) +"ZY" = ( +/obj/structure/safe, +/turf/simulated/floor/plasteel, +/area/game_test) + +(1,1,1) = {" +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +"} +(2,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(3,1,1) = {" +Od +rT +nK +rT +aG +rT +cH +rT +wb +rT +VM +rT +JP +rT +rT +BX +rT +Od +"} +(4,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(5,1,1) = {" +Od +rT +OE +rT +FZ +rT +Xt +rT +AI +rT +Od +eY +UT +rT +rT +rT +rT +Od +"} +(6,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(7,1,1) = {" +Od +rT +qt +rT +sR +rT +Xt +rT +wr +rT +DQ +rT +FH +rT +rT +rT +rT +Od +"} +(8,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +dG +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(9,1,1) = {" +Od +rT +ve +rT +AG +rT +dG +Wr +dG +rT +le +rT +yd +rT +rT +rT +rT +Od +"} +(10,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +dG +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(11,1,1) = {" +Od +rT +lH +rT +bw +rT +tQ +rT +Ye +rT +GO +rT +sE +rT +zK +rT +rT +Od +"} +(12,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(13,1,1) = {" +Od +rT +RN +rT +kT +rT +NN +rT +eN +rT +ZY +rT +jj +rT +Cd +rT +rT +Od +"} +(14,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(15,1,1) = {" +Od +rT +pS +rT +kg +rT +wn +rT +ms +rT +cf +rT +tn +rT +fA +rT +rT +Od +"} +(16,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(17,1,1) = {" +Od +rT +Sw +rT +RH +rT +Uu +rT +yn +rT +YV +rT +nj +rT +QL +rT +rT +Od +"} +(18,1,1) = {" +Od +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +rT +Od +"} +(19,1,1) = {" +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +Od +"} diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 84afcd86611..73bbdc7b49f 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -52,17 +52,18 @@ . += "The magic in [src] is weak, it will be ready to use again in [get_ETA()]." . += "[src] is [anchored ? "":"not "]secured to the floor." -/obj/structure/cult/functional/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/cult/functional/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user)) if(user.holy_check()) - return + return ITEM_INTERACT_COMPLETE anchored = !anchored to_chat(user, "You [anchored ? "":"un"]secure [src] [anchored ? "to":"from"] the floor.") if(!anchored) icon_state = GET_CULT_DATA(get_icon("[initial(icon_state)]_off"), "[initial(icon_state)]_off") else icon_state = GET_CULT_DATA(get_icon(initial(icon_state)), initial(icon_state)) - return + return ITEM_INTERACT_COMPLETE + return ..() /obj/structure/cult/functional/attack_hand(mob/living/user) @@ -180,22 +181,22 @@ . = ..() icon_state = GET_CULT_DATA(forge_icon_state, "forge") -/obj/structure/cult/functional/forge/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/cult/functional/forge/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/grab)) var/obj/item/grab/G = I if(!iscarbon(G.affecting)) - return FALSE + return ITEM_INTERACT_COMPLETE if(G.affecting == LAVA_PROOF) to_chat(user, "[G.affecting] is immune to lava!") - return FALSE + return ITEM_INTERACT_COMPLETE if(G.affecting.stat == DEAD) to_chat(user, "[G.affecting] is dead!") - return FALSE + return ITEM_INTERACT_COMPLETE var/mob/living/carbon/human/C = G.affecting var/obj/item/organ/external/head/head = C.get_organ("head") if(!head) to_chat(user, "[C] has no head!") - return FALSE + return ITEM_INTERACT_COMPLETE C.visible_message("[user] dunks [C]'s face into [src]'s lava!", "[user] dunks your face into [src]'s lava!") @@ -205,7 +206,8 @@ C.UpdateDamageIcon() add_attack_logs(user, C, "Lava-dunked into [src]") user.changeNext_move(CLICK_CD_MELEE) - return TRUE + return ITEM_INTERACT_COMPLETE + return ..() GLOBAL_LIST_INIT(blacklisted_pylon_turfs, typecacheof(list( diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index c7736350d75..35185b94547 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -288,13 +288,13 @@ . += "A Wraith, which does high damage and can jaunt through walls, though it is quite fragile." . += "A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow." -/obj/structure/constructshell/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) +/obj/structure/constructshell/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/soulstone)) var/obj/item/soulstone/SS = I if(!SS.can_use(user)) to_chat(user, "An overwhelming feeling of dread comes over you as you attempt to place the soulstone into the shell.") user.Confused(20 SECONDS) - return + return ITEM_INTERACT_COMPLETE SS.transfer_soul("CONSTRUCT", src, user) SS.was_used() else diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 7a2047fb0a1..c4d39c0177c 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -15,12 +15,12 @@ QDEL_NULL(brain) return ..() -/obj/structure/ai_core/attackby__legacy__attackchain(obj/item/P, mob/user, params) +/obj/structure/ai_core/item_interaction(mob/living/user, obj/item/P, list/modifiers) switch(state) if(EMPTY_CORE) if(istype(P, /obj/item/circuitboard/aicore)) if(!user.drop_item()) - return + return ITEM_INTERACT_COMPLETE playsound(loc, P.usesound, 50, 1) to_chat(user, "You place the circuit board inside the frame.") update_icon(UPDATE_ICON_STATE) @@ -28,7 +28,7 @@ P.forceMove(src) circuit = P update_icon(UPDATE_ICON_STATE) - return + return ITEM_INTERACT_COMPLETE if(SCREWED_CORE) if(istype(P, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/C = P @@ -41,7 +41,7 @@ update_icon(UPDATE_ICON_STATE) else to_chat(user, "You need five lengths of cable to wire the AI core!") - return + return ITEM_INTERACT_COMPLETE if(CABLED_CORE) if(istype(P, /obj/item/stack/sheet/rglass)) var/obj/item/stack/sheet/rglass/G = P @@ -54,73 +54,73 @@ update_icon(UPDATE_ICON_STATE) else to_chat(user, "You need two sheets of reinforced glass to insert them into the AI core!") - return + return ITEM_INTERACT_COMPLETE if(istype(P, /obj/item/ai_module/purge)) laws.clear_inherent_laws() to_chat(usr, "Law module applied.") - return + return ITEM_INTERACT_COMPLETE if(istype(P, /obj/item/ai_module/freeform)) var/obj/item/ai_module/freeform/M = P if(!M.newFreeFormLaw) to_chat(usr, "No law detected on module, please create one.") - return + return ITEM_INTERACT_COMPLETE laws.add_supplied_law(M.lawpos, M.newFreeFormLaw) to_chat(usr, "Added a freeform law.") - return + return ITEM_INTERACT_COMPLETE if(istype(P, /obj/item/ai_module/syndicate)) var/obj/item/ai_module/syndicate/M = P if(!M.newFreeFormLaw) to_chat(usr, "No law detected on module, please create one.") - return + return ITEM_INTERACT_COMPLETE laws.add_ion_law(M.newFreeFormLaw) to_chat(usr, "Added a hacked law.") - return + return ITEM_INTERACT_COMPLETE if(istype(P, /obj/item/ai_module)) var/obj/item/ai_module/M = P if(!M.laws) to_chat(usr, "This AI module can not be applied directly to AI cores.") - return + return ITEM_INTERACT_COMPLETE laws = M.laws to_chat(usr, "Added [M.laws.name] laws.") - return + return ITEM_INTERACT_COMPLETE if(istype(P, /obj/item/mmi) && !brain) var/obj/item/mmi/M = P if(!M.brainmob) to_chat(user, "Sticking an empty [P] into the frame would sort of defeat the purpose.") - return + return ITEM_INTERACT_COMPLETE if(M.brainmob.stat == DEAD) to_chat(user, "Sticking a dead [P] into the frame would sort of defeat the purpose.") - return + return ITEM_INTERACT_COMPLETE if(!M.brainmob.client) to_chat(user, "Sticking an inactive [M.name] into the frame would sort of defeat the purpose.") - return + return ITEM_INTERACT_COMPLETE if(jobban_isbanned(M.brainmob, "AI") || jobban_isbanned(M.brainmob, "nonhumandept")) to_chat(user, "This [P] does not seem to fit.") - return + return ITEM_INTERACT_COMPLETE if(!M.brainmob.mind) to_chat(user, "This [M.name] is mindless!") - return + return ITEM_INTERACT_COMPLETE if(istype(P, /obj/item/mmi/syndie)) to_chat(user, "This MMI does not seem to fit!") - return + return ITEM_INTERACT_COMPLETE if(!user.drop_item()) - return + return ITEM_INTERACT_COMPLETE M.forceMove(src) brain = M to_chat(user, "You add [M.name] to the frame.") update_icon(UPDATE_ICON_STATE) - return + return ITEM_INTERACT_COMPLETE return ..() diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 731e02eaf1a..60f4b820663 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -686,7 +686,7 @@ I.play_tool_sound(src) update_icon() -/obj/structure/computerframe/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/computerframe/item_interaction(mob/living/user, obj/item/I, list/modifiers) switch(state) if(STATE_EMPTY) if(!istype(I, /obj/item/circuitboard)) @@ -695,11 +695,11 @@ var/obj/item/circuitboard/B = I if(B.board_type != "computer") to_chat(user, "[src] does not accept circuit boards of this type!") - return + return ITEM_INTERACT_COMPLETE if(!B.build_path) to_chat(user, "This is not a functional computer circuit board!") - return + return ITEM_INTERACT_COMPLETE B.play_tool_sound(src) to_chat(user, "You place [B] inside [src].") @@ -709,7 +709,7 @@ B.forceMove(src) circuit = B update_icon() - return + return ITEM_INTERACT_COMPLETE if(STATE_NOWIRES) if(!istype(I, /obj/item/stack/cable_coil)) @@ -718,20 +718,20 @@ var/obj/item/stack/cable_coil/C = I if(C.get_amount() < 5) to_chat(user, "You need five lengths of cable to wire the frame.") - return + return ITEM_INTERACT_COMPLETE C.play_tool_sound(src) to_chat(user, "You start to add cables to the frame.") if(!do_after(user, 2 SECONDS * C.toolspeed, target = src)) - return + return ITEM_INTERACT_COMPLETE if(C.get_amount() < 5 || !C.use(5)) to_chat(user, "At some point during construction you lost some cable. Make sure you have five lengths before trying again.") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You add cables to the frame.") state = STATE_WIRES update_icon() - return + return ITEM_INTERACT_COMPLETE if(STATE_WIRES) if(!istype(I, /obj/item/stack/sheet/glass)) @@ -740,20 +740,20 @@ var/obj/item/stack/sheet/glass/G = I if(G.get_amount() < 2) to_chat(user, "You need two sheets of glass for this.") - return + return ITEM_INTERACT_COMPLETE G.play_tool_sound(src) to_chat(user, "You start to add the glass panel to the frame.") if(!do_after(user, 2 SECONDS * G.toolspeed, target = src)) - return + return ITEM_INTERACT_COMPLETE if(G.get_amount() < 2 || !G.use(2)) to_chat(user, "At some point during construction you lost some glass. Make sure you have two sheets before trying again.") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You put in the glass panel.") state = STATE_GLASS update_icon() - return + return ITEM_INTERACT_COMPLETE return ..() diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 2de04ec3ec2..8f197336525 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -92,22 +92,21 @@ bar_material = WOOD stacktype = /obj/item/stack/sheet/wood - -/obj/structure/barricade/wooden/attackby__legacy__attackchain(obj/item/I, mob/user) +/obj/structure/barricade/wooden/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I,/obj/item/stack/sheet/wood)) var/obj/item/stack/sheet/wood/W = I if(W.get_amount() < 5) to_chat(user, "You need at least five wooden planks to make a wall!") - return + return ITEM_INTERACT_COMPLETE else to_chat(user, "You start adding [I] to [src]...") if(do_after(user, 50, target = src)) if(!W.use(5)) - return + return ITEM_INTERACT_COMPLETE var/turf/T = get_turf(src) T.ChangeTurf(/turf/simulated/wall/mineral/wood/nonmetal) qdel(src) - return //return is need to prevent people from exploiting zero-hit cooldowns with the do_after here + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/barricade/wooden/crowbar_act(mob/living/user, obj/item/I) @@ -375,8 +374,7 @@ if(!target_turf2.is_blocked_turf()) connected_shields += new barricade_type(target_turf2, src, FALSE, direction, dir_right) - -/obj/structure/dropwall_generator/attacked_by__legacy__attackchain(obj/item/I, mob/living/user) //No, you can not just go up to the generator and whack it. Central shield needs to go down first. +/obj/structure/dropwall_generator/attacked_by(obj/item/I, mob/living/user) if(protected) visible_message("[src]'s shield absorbs the blow!") core_shield.take_damage(I.force, I.damtype, MELEE, TRUE) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index b5f4bb4cbd0..eb4e9d408e8 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -402,57 +402,57 @@ /obj/structure/firelock_frame/update_icon_state() icon_state = "frame[constructionStep]" -/obj/structure/firelock_frame/attackby__legacy__attackchain(obj/item/C, mob/user) +/obj/structure/firelock_frame/item_interaction(mob/living/user, obj/item/C, list/modifiers) switch(constructionStep) if(CONSTRUCTION_PANEL_OPEN) if(istype(C, /obj/item/stack/sheet/plasteel)) var/obj/item/stack/sheet/plasteel/P = C if(reinforced) to_chat(user, "[src] is already reinforced.") - return + return ITEM_INTERACT_COMPLETE if(P.get_amount() < 2) to_chat(user, "You need more plasteel to reinforce [src].") - return + return ITEM_INTERACT_COMPLETE user.visible_message("[user] begins reinforcing [src]...", \ "You begin reinforcing [src]...") playsound(get_turf(src), C.usesound, 50, 1) if(do_after(user, 60 * C.toolspeed, target = src)) if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || P.get_amount() < 2 || !P) - return + return ITEM_INTERACT_COMPLETE user.visible_message("[user] reinforces [src].", \ "You reinforce [src].") playsound(get_turf(src), C.usesound, 50, 1) P.use(2) reinforced = 1 - return + return ITEM_INTERACT_COMPLETE if(CONSTRUCTION_GUTTED) if(iscoil(C)) var/obj/item/stack/cable_coil/B = C if(B.get_amount() < 5) to_chat(user, "You need more wires to add wiring to [src].") - return + return ITEM_INTERACT_COMPLETE user.visible_message("[user] begins wiring [src]...", \ "You begin adding wires to [src]...") playsound(get_turf(src), B.usesound, 50, 1) if(do_after(user, 60 * B.toolspeed, target = src)) if(constructionStep != CONSTRUCTION_GUTTED || B.get_amount() < 5 || !B) - return + return ITEM_INTERACT_COMPLETE user.visible_message("[user] adds wires to [src].", \ "You wire [src].") playsound(get_turf(src), B.usesound, 50, 1) B.use(5) constructionStep = CONSTRUCTION_WIRES_EXPOSED update_icon() - return + return ITEM_INTERACT_COMPLETE if(CONSTRUCTION_NOCIRCUIT) if(istype(C, /obj/item/firelock_electronics)) user.visible_message("[user] starts adding [C] to [src]...", \ "You begin adding a circuit board to [src]...") playsound(get_turf(src), C.usesound, 50, 1) if(!do_after(user, 40 * C.toolspeed, target = src)) - return + return ITEM_INTERACT_COMPLETE if(constructionStep != CONSTRUCTION_NOCIRCUIT) - return + return ITEM_INTERACT_COMPLETE user.drop_item() qdel(C) user.visible_message("[user] adds a circuit to [src].", \ @@ -460,7 +460,7 @@ playsound(get_turf(src), C.usesound, 50, 1) constructionStep = CONSTRUCTION_GUTTED update_icon() - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/firelock_frame/crowbar_act(mob/user, obj/item/I) diff --git a/code/game/machinery/machine_frame.dm b/code/game/machinery/machine_frame.dm index b727d972329..54f23c77257 100644 --- a/code/game/machinery/machine_frame.dm +++ b/code/game/machinery/machine_frame.dm @@ -89,7 +89,7 @@ else icon_state = "box_0" -/obj/structure/machine_frame/attackby__legacy__attackchain(obj/item/P, mob/living/user, params) +/obj/structure/machine_frame/item_interaction(mob/living/user, obj/item/P, list/modifiers) switch(state) if(MACHINE_FRAME_EMPTY) if(istype(P, /obj/item/stack/cable_coil)) @@ -104,16 +104,16 @@ update_icon(UPDATE_ICON_STATE) else to_chat(user, "At some point during construction you lost some cable. Make sure you have five lengths before trying again.") - return + return ITEM_INTERACT_COMPLETE else to_chat(user, "You need five lengths of cable to wire the frame.") - return + return ITEM_INTERACT_COMPLETE if(iswrench(P)) P.play_tool_sound(src) to_chat(user, "You dismantle the frame.") deconstruct(TRUE) - return + return ITEM_INTERACT_COMPLETE if(MACHINE_FRAME_WIRED) // see wirecutter_act() @@ -122,7 +122,7 @@ if(B.board_type == frame_type) if(!B.build_path) to_chat(user, "This is not a functional machine board!") - return + return ITEM_INTERACT_COMPLETE playsound(src.loc, B.usesound, 50, 1) to_chat(user, "You add the circuit board to the frame.") circuit = P @@ -134,7 +134,7 @@ update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE) else to_chat(user, "This frame does not accept circuit boards of this type!") - return + return ITEM_INTERACT_COMPLETE if(MACHINE_FRAME_CIRCUITBOARD) // see crowbar_act() @@ -165,7 +165,7 @@ replacer.play_rped_sound() update_appearance(UPDATE_DESC) - return + return ITEM_INTERACT_COMPLETE if(isitem(P)) var/success @@ -189,11 +189,11 @@ components += P req_components[I]-- update_appearance(UPDATE_DESC) - return 1 + return ITEM_INTERACT_COMPLETE if(!success) to_chat(user, "You cannot add that to the machine!") - return 0 - return + return ITEM_INTERACT_COMPLETE + return ITEM_INTERACT_COMPLETE if(user.a_intent == INTENT_HARM) return ..() diff --git a/code/game/objects/items/bio_chips/bio_chip_stealth.dm b/code/game/objects/items/bio_chips/bio_chip_stealth.dm index 2e9fa41da33..6ffbfa1d6cb 100644 --- a/code/game/objects/items/bio_chips/bio_chip_stealth.dm +++ b/code/game/objects/items/bio_chips/bio_chip_stealth.dm @@ -109,8 +109,9 @@ move_speed_multiplier = 0.5 // You can move at run speed while in this box. material_drop = null -/obj/structure/closet/cardboard/agent/attackby__legacy__attackchain(obj/item/I, mob/living/user) - return +/obj/structure/closet/cardboard/agent/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by)) /obj/structure/closet/cardboard/agent/open() . = ..() diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index ac69cde165b..c92e69f09ea 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -27,20 +27,20 @@ close_sound_volume = 15 var/item_path = /obj/item/bodybag -/obj/structure/closet/body_bag/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/closet/body_bag/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(is_pen(I)) var/t = rename_interactive(user, I) if(isnull(t)) - return + return ITEM_INTERACT_COMPLETE cut_overlays() if(t) add_overlay("bodybag_label") - return + return ITEM_INTERACT_COMPLETE if(istype(I, /obj/item/wirecutters)) to_chat(user, "You cut the tag off the bodybag.") name = initial(name) cut_overlays() - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/closet/body_bag/welder_act(mob/user, obj/item/I) diff --git a/code/game/objects/items/picket_signs.dm b/code/game/objects/items/picket_signs.dm index 7f6517172c7..1590eb77e9b 100644 --- a/code/game/objects/items/picket_signs.dm +++ b/code/game/objects/items/picket_signs.dm @@ -65,7 +65,6 @@ icon_state = "floor_sign" /// What does the sign say? var/label = "" - new_attack_chain = TRUE /obj/structure/custom_sign/New(turf/loc, new_label) . = ..() diff --git a/code/game/objects/items/sport.dm b/code/game/objects/items/sport.dm index 31fb89fb4d5..5d0dce17d29 100644 --- a/code/game/objects/items/sport.dm +++ b/code/game/objects/items/sport.dm @@ -67,21 +67,21 @@ density = TRUE pass_flags_self = LETPASSTHROW | PASSTAKE -/obj/structure/holohoop/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/holohoop/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/grab) && get_dist(src, user) <= 1) var/obj/item/grab/G = W if(G.state < GRAB_AGGRESSIVE) to_chat(user, "You need a better grip to do that!") - return + return ITEM_INTERACT_COMPLETE G.affecting.forceMove(loc) G.affecting.Weaken(10 SECONDS) visible_message("[G.assailant] dunks [G.affecting] into [src]!") qdel(W) - return + return ITEM_INTERACT_COMPLETE else if(isitem(W) && get_dist(src,user) <= 1) user.drop_item(src) visible_message("[user] dunks [W] into [src]!") - return + return ITEM_INTERACT_COMPLETE /obj/structure/holohoop/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(isitem(AM) && !isprojectile(AM)) diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index d75a14921eb..9322bfddd4b 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -204,7 +204,7 @@ // into the box. if(istype(user.pulling, /obj/structure/ore_box)) var/obj/structure/ore_box/box = user.pulling - box.attackby__legacy__attackchain(src, user) + box.item_interaction(user, src) /obj/item/storage/bag/ore/cyborg name = "cyborg mining satchel" diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 28a9d08bb2e..f1189ccb50c 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -13,6 +13,8 @@ /// How long this takes to unbuckle yourself from. var/unbuckle_time = 0 SECONDS + new_attack_chain = TRUE + /obj/structure/New() ..() if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index dacefab579a..98909ada9fe 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -254,7 +254,6 @@ LINEN BINS anchored = TRUE resistance_flags = FLAMMABLE max_integrity = 70 - new_attack_chain = TRUE var/amount = 20 var/list/sheets = list() var/obj/item/hidden = null @@ -308,22 +307,23 @@ LINEN BINS if(istype(used, /obj/item/bedsheet)) if(!user.drop_item()) to_chat(user, "[used] is stuck to your hand!") - return + return ITEM_INTERACT_COMPLETE used.forceMove(src) sheets.Add(used) amount++ update_icon(UPDATE_ICON_STATE) to_chat(user, "You put [used] in [src].") + return ITEM_INTERACT_COMPLETE else if(amount && !hidden && used.w_class < WEIGHT_CLASS_BULKY) //make sure there's sheets to hide it among, make sure nothing else is hidden in there. if(used.flags & ABSTRACT) - return + return ITEM_INTERACT_COMPLETE if(!user.drop_item()) to_chat(user, "[used] is stuck to your hand!") - return + return ITEM_INTERACT_COMPLETE used.forceMove(src) hidden = used to_chat(user, "You hide [used] among the sheets.") - + return ITEM_INTERACT_COMPLETE /obj/structure/bedsheetbin/attack_hand(mob/user) diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm index 71c1a237248..6b21f9681b1 100644 --- a/code/game/objects/structures/coathanger.dm +++ b/code/game/objects/structures/coathanger.dm @@ -15,7 +15,7 @@ coat = null update_icon(UPDATE_OVERLAYS) -/obj/structure/coatrack/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/structure/coatrack/item_interaction(mob/living/user, obj/item/W, list/modifiers) var/can_hang = FALSE for(var/T in allowed) if(istype(W,T)) @@ -26,7 +26,7 @@ user.drop_item(src) coat.forceMove(src) update_icon(UPDATE_OVERLAYS) - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/coatrack/CanPass(atom/movable/mover, border_dir) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 4ed92e38e14..09a9e03db1a 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -284,11 +284,11 @@ if(!broken && !(flags & NODECONSTRUCT)) bust_open() -/obj/structure/closet/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/closet/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/rcs) && !opened) var/obj/item/rcs/E = W E.try_send_container(user, src) - return + return ITEM_INTERACT_COMPLETE if(opened) if(istype(W, /obj/item/grab)) @@ -298,26 +298,28 @@ else to_chat(user, "[src] is too small to stuff [G.affecting] into!") if(istype(W, /obj/item/tk_grab)) - return FALSE + return // passthrough if(user.a_intent != INTENT_HELP) // Stops you from putting your baton in the closet on accident - return + return ITEM_INTERACT_COMPLETE if(isrobot(user) && !istype(W.loc, /obj/item/gripper)) - return + return ITEM_INTERACT_COMPLETE if(!user.drop_item()) //couldn't drop the item to_chat(user, "\The [W] is stuck to your hand, you cannot put it in \the [src]!") - return + return ITEM_INTERACT_COMPLETE if(W.loc != user.loc) // It went somewhere else, don't teleport it back. - return + return ITEM_INTERACT_COMPLETE if(W) W.forceMove(loc) - return TRUE // It's resolved. No afterattack needed. Stops you from emagging lockers when putting in an emag + return ITEM_INTERACT_COMPLETE else if(can_be_emaged && (istype(W, /obj/item/card/emag) || istype(W, /obj/item/melee/energy/blade) && !broken)) emag_act(user) + return ITEM_INTERACT_COMPLETE else if(istype(W, /obj/item/stack/package_wrap)) - return + return ITEM_INTERACT_COMPLETE else if(user.a_intent != INTENT_HARM) closed_item_click(user) + return ITEM_INTERACT_COMPLETE else return ..() diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index 72e993d308e..1e692232876 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -68,7 +68,7 @@ /obj/structure/closet/cardboard/welder_act() return -/obj/structure/closet/cardboard/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/structure/closet/cardboard/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(src.opened) if(istype(W, /obj/item/wirecutters)) var/obj/item/wirecutters/WC = W @@ -76,26 +76,26 @@ for(var/mob/M in viewers(src)) M.show_message("\The [src] has been cut apart by [user] with \the [WC].", 3, "You hear cutting.", 2) qdel(src) - return + return ITEM_INTERACT_COMPLETE if(is_pen(W)) var/decalselection = tgui_input_list(user, "Please select a decal", "Paint Box", list("Atmospherics", "Bartender", "Barber", "Blueshield", "Captain", "Cargo", "Chief Engineer", "Chaplain", "Chef", "Chemist", "Assistant", "Clown", "CMO", "Coroner", "Detective", "Engineering", "Genetics", "HOP", "HOS", "Hydroponics", "Internal Affairs Agent", "Janitor", "Magistrate", "Medical", "Mime", "Mining", "NT Representative", "Paramedic", "Prisoner", "Research Director", "Security", "Syndicate", "Therapist", "Virology", "Warden", "Xenobiology")) if(!decalselection) - return + return ITEM_INTERACT_COMPLETE if(user.incapacitated()) to_chat(user, "You're in no condition to perform this action.") - return + return ITEM_INTERACT_COMPLETE if(W != user.get_active_hand()) to_chat(user, "You must be holding the pen to perform this action.") - return + return ITEM_INTERACT_COMPLETE if(!Adjacent(user)) to_chat(user, "You have moved too far away from the cardboard box.") - return + return ITEM_INTERACT_COMPLETE decalselection = replacetext(decalselection, " ", "_") decalselection = lowertext(decalselection) custom_skin = "_[decalselection]" update_icon() // a proc declared in the closets parent file used to update opened/closed sprites on normal closets - return - return ..() + + return ITEM_INTERACT_COMPLETE diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm index 2b45b4a04ef..e52e7730991 100644 --- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm +++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm @@ -29,7 +29,7 @@ else . += "It is damaged beyond repair." -/obj/structure/closet/fireaxecabinet/attackby__legacy__attackchain(obj/item/O as obj, mob/living/user as mob) //Marker -Agouri +/obj/structure/closet/fireaxecabinet/item_interaction(mob/living/user, obj/item/O, list/modifiers) if(isrobot(user) || locked) if(istype(O, /obj/item/multitool)) to_chat(user, "Resetting circuitry...") @@ -38,14 +38,14 @@ locked = FALSE to_chat(user, " You disable the locking modules.") update_icon(UPDATE_ICON_STATE) - return + return ITEM_INTERACT_COMPLETE else if(isitem(O)) user.changeNext_move(CLICK_CD_MELEE) var/obj/item/W = O if(smashed || localopened) if(localopened) operate_panel() - return + return ITEM_INTERACT_COMPLETE else user.do_attack_animation(src) playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time @@ -59,16 +59,16 @@ locked = FALSE localopened = TRUE update_icon(UPDATE_ICON_STATE) - return + return ITEM_INTERACT_COMPLETE if(istype(O, /obj/item/fireaxe) && localopened) if(!fireaxe) var/obj/item/fireaxe/F = O if(HAS_TRAIT(F, TRAIT_WIELDED)) to_chat(user, "Unwield \the [F] first.") - return + return ITEM_INTERACT_COMPLETE if(!user.unequip(F, FALSE)) to_chat(user, "\The [F] stays stuck to your hands!") - return + return ITEM_INTERACT_COMPLETE fireaxe = F has_axe = "full" contents += F @@ -76,25 +76,27 @@ update_icon(UPDATE_ICON_STATE) else if(smashed) - return + return ITEM_INTERACT_COMPLETE else operate_panel() + return ITEM_INTERACT_COMPLETE else if(smashed) - return + return ITEM_INTERACT_COMPLETE if(istype(O, /obj/item/multitool)) if(localopened) operate_panel() - return + return ITEM_INTERACT_COMPLETE else to_chat(user, "Resetting circuitry...") playsound(user, 'sound/machines/lockenable.ogg', 50, 1) if(do_after(user, 20 * O.toolspeed, target = src)) locked = TRUE to_chat(user, " You re-enable the locking modules.") - return + return ITEM_INTERACT_COMPLETE else operate_panel() + return ITEM_INTERACT_COMPLETE /obj/structure/closet/fireaxecabinet/attack_hand(mob/user as mob) if(locked) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/depot_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/depot_closets.dm index faec4fe0ae1..e19cc0773c7 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/depot_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/depot_closets.dm @@ -36,10 +36,10 @@ return return ..() -/obj/structure/closet/secure_closet/depot/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/closet/secure_closet/depot/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/rcs)) to_chat(user, "Bluespace interference prevents [W] from locking onto [src]!") - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/closet/secure_closet/depot/emp_act(severity) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index 892205426e2..5c31946fd21 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -34,25 +34,25 @@ new /obj/item/storage/backpack/satchel/withwallet( src ) new /obj/item/radio/headset( src ) -/obj/structure/closet/secure_closet/personal/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/closet/secure_closet/personal/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(opened || !istype(W, /obj/item/card/id)) return ..() if(broken) to_chat(user, "The locker appears to be broken.") - return + return ITEM_INTERACT_COMPLETE if(user.loc == src) to_chat(user, "You can't reach the lock from inside.") - return + return ITEM_INTERACT_COMPLETE if(istype(W, /obj/item/card/id/guest)) to_chat(user, "Invalid identification card.") - return + return ITEM_INTERACT_COMPLETE var/obj/item/card/id/I = W if(!I || !I.registered_name) - return + return ITEM_INTERACT_COMPLETE if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name))) //they can open all lockers, or nobody owns this, or they own this locker @@ -68,3 +68,5 @@ else to_chat(user, "Access denied.") + + return ITEM_INTERACT_COMPLETE diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 639f59dae6b..91d88325b26 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -85,9 +85,9 @@ opened = FALSE return TRUE -/obj/structure/closet/crate/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/closet/crate/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(!opened && try_rig(W, user)) - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/closet/crate/toggle(mob/user, by_hand = FALSE) @@ -311,18 +311,18 @@ return FALSE return TRUE -/obj/structure/closet/crate/secure/personal/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/closet/crate/secure/personal/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(opened || !istype(I, /obj/item/card/id)) return ..() if(broken) to_chat(user, "It appears to be broken.") - return FALSE + return ITEM_INTERACT_COMPLETE var/obj/item/card/id/id = I if(!is_usable_id(id)) to_chat(user, "Invalid identification card.") - return FALSE + return ITEM_INTERACT_COMPLETE if(registered_name && allowed(user)) return ..() @@ -330,12 +330,12 @@ if(!registered_name) registered_name = id.registered_name to_chat(user, "Crate reserved") - return TRUE + return ITEM_INTERACT_COMPLETE if(registered_name == id.registered_name) return ..() - return FALSE + return ITEM_INTERACT_COMPLETE /obj/structure/closet/crate/plastic name = "plastic crate" diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 4195f5f0031..7633872defb 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -29,11 +29,10 @@ to_chat(user, "You need a crowbar to pry this open!") return -/obj/structure/largecrate/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/structure/largecrate/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(user.a_intent != INTENT_HARM) attack_hand(user) - else - return ..() + return ITEM_INTERACT_COMPLETE /obj/structure/largecrate/crowbar_act(mob/living/user, obj/item/I) . = TRUE diff --git a/code/game/objects/structures/curtains.dm b/code/game/objects/structures/curtains.dm index 8bfb3fc0126..33b654ac3b3 100644 --- a/code/game/objects/structures/curtains.dm +++ b/code/game/objects/structures/curtains.dm @@ -8,7 +8,6 @@ face_while_pulling = FALSE layer = SHOWER_CLOSED_LAYER opacity = TRUE - new_attack_chain = TRUE var/assembled = TRUE var/overlay_color = "#ffffff" var/overlay_alpha = 255 diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 13b4fd258a2..f8f1978e9e4 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -130,30 +130,32 @@ if(!open && !broken) . += "glassbox_closed" -/obj/structure/displaycase/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/displaycase/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(I.GetID()) if(!openable) to_chat(user, "There is no ID scanner, looks like this one is sealed shut.") - return + return ITEM_INTERACT_COMPLETE if(broken) to_chat(user, "[src] is broken, the ID lock won't do anything.") - return + return ITEM_INTERACT_COMPLETE if(allowed(user) || emagged) to_chat(user, "You use [I] to [open ? "close" : "open"] [src].") toggle_lock() else to_chat(user, "Access denied.") + return ITEM_INTERACT_COMPLETE else if(open && !showpiece) if(!(I.flags & (ABSTRACT | DROPDEL)) && user.drop_item()) I.forceMove(src) showpiece = I to_chat(user, "You put [I] on display") update_icon() + return ITEM_INTERACT_COMPLETE else if(istype(I, /obj/item/stack/sheet/glass) && broken) var/obj/item/stack/sheet/glass/G = I if(G.get_amount() < 2) to_chat(user, "You need two glass sheets to fix the case!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start fixing [src]...") if(do_after(user, 20, target = src)) G.use(2) @@ -161,6 +163,7 @@ open = FALSE obj_integrity = max_integrity update_icon(UPDATE_OVERLAYS) + return ITEM_INTERACT_COMPLETE else return ..() @@ -231,7 +234,7 @@ icon_state = "glassbox_chassis" var/obj/item/airlock_electronics/electronics -/obj/structure/displaycase_chassis/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/displaycase_chassis/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/airlock_electronics)) to_chat(user, "You start installing the electronics into [src]...") playsound(loc, I.usesound, 50, TRUE) @@ -242,12 +245,12 @@ electronics = new_electronics to_chat(user, "You install the airlock electronics.") electronics.is_installed = TRUE - + return ITEM_INTERACT_COMPLETE else if(istype(I, /obj/item/stack/sheet/glass)) var/obj/item/stack/sheet/glass/G = I if(G.get_amount() < 10) to_chat(user, "You need ten glass sheets to do this!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start adding [G] to [src]...") if(do_after(user, 20, target = src)) G.use(10) @@ -261,6 +264,7 @@ else display.req_access = electronics.selected_accesses qdel(src) + return ITEM_INTERACT_COMPLETE else return ..() diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index c5464774f6b..e7c50db3dc2 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -55,7 +55,8 @@ else . += "There is a small paper placard on the assembly[doorname]." -/obj/structure/door_assembly/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/door_assembly/item_interaction(mob/living/user, obj/item/W, list/modifiers) + . = ITEM_INTERACT_COMPLETE if(is_pen(W)) // The door assembly gets renamed to "Assembly - Foobar", // but the `t` returned from the proc is just "Foobar" without the prefix. diff --git a/code/game/objects/structures/engicart.dm b/code/game/objects/structures/engicart.dm index 51d027ecc24..a476cc034a9 100644 --- a/code/game/objects/structures/engicart.dm +++ b/code/game/objects/structures/engicart.dm @@ -5,7 +5,6 @@ icon_state = "cart" face_while_pulling = FALSE density = TRUE - new_attack_chain = TRUE var/obj/item/stack/sheet/glass/my_glass = null var/obj/item/stack/sheet/metal/my_metal = null var/obj/item/stack/sheet/plasteel/my_plasteel = null @@ -94,7 +93,7 @@ to_chat(user, fail_msg) return - if(!put_in_cart(used, user)) + if(!put_in_cart(used, user)) return my_flashlight = used diff --git a/code/game/objects/structures/extinguisher_cabinet.dm b/code/game/objects/structures/extinguisher_cabinet.dm index 06244919f9b..5c22c40fa9f 100644 --- a/code/game/objects/structures/extinguisher_cabinet.dm +++ b/code/game/objects/structures/extinguisher_cabinet.dm @@ -61,7 +61,7 @@ has_extinguisher = null update_icon(UPDATE_ICON_STATE) -/obj/structure/extinguisher_cabinet/attackby__legacy__attackchain(obj/item/O, mob/user, params) +/obj/structure/extinguisher_cabinet/item_interaction(mob/living/user, obj/item/O, list/modifiers) if(isrobot(user) || isalien(user)) return if(istype(O, /obj/item/extinguisher)) diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index cbc23fcebd2..3a42bdb41c0 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -114,13 +114,14 @@ qdel(src) return T -/obj/structure/falsewall/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/falsewall/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(opening) to_chat(user, "You must wait until the door has stopped moving.") - return + return ITEM_INTERACT_COMPLETE - if(istype(W, /obj/item/gun/energy/plasmacutter) || istype(W, /obj/item/pickaxe/drill/diamonddrill) || istype(W, /obj/item/pickaxe/drill/jackhammer) || istype(W, /obj/item/melee/energy/blade) || istype(W, /obj/item/pyro_claws)) + if(istype(used, /obj/item/gun/energy/plasmacutter) || istype(used, /obj/item/pickaxe/drill/diamonddrill) || istype(used, /obj/item/pickaxe/drill/jackhammer) || istype(used, /obj/item/melee/energy/blade) || istype(used, /obj/item/pyro_claws)) dismantle(user, TRUE) + return ITEM_INTERACT_COMPLETE /obj/structure/falsewall/attack_animal(mob/living/simple_animal/M) . = ..() @@ -272,15 +273,14 @@ canSmoothWith = list(SMOOTH_GROUP_PLASMA_WALLS) cares_about_temperature = TRUE -/obj/structure/falsewall/plasma/attackby__legacy__attackchain(obj/item/W, mob/user, params) - if(W.get_heat() > 300) +/obj/structure/falsewall/plasma/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(used.get_heat() > 300) var/turf/T = locate(user) message_admins("Plasma falsewall ignited by [key_name_admin(user)] in [ADMIN_VERBOSEJMP(T)]") log_game("Plasma falsewall ignited by [key_name(user)] in [AREACOORD(T)]") investigate_log("was ignited by [key_name(user)]",INVESTIGATE_ATMOS) burnbabyburn() - else - return ..() + return ITEM_INTERACT_COMPLETE /obj/structure/falsewall/plasma/proc/burnbabyburn(user) playsound(src, 'sound/items/welder.ogg', 100, 1) diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm index 6617e4295a0..2aa7b9eb8a7 100644 --- a/code/game/objects/structures/fence.dm +++ b/code/game/objects/structures/fence.dm @@ -121,16 +121,16 @@ return update_cut_status() -/obj/structure/fence/attackby__legacy__attackchain(obj/item/C, mob/user) +/obj/structure/fence/item_interaction(mob/living/user, obj/item/C, list/modifiers) if(shock(user, 90)) - return + return ITEM_INTERACT_COMPLETE if(istype(C, /obj/item/stack/rods)) if(hole_size == NO_HOLE) - return + return ITEM_INTERACT_COMPLETE var/obj/item/stack/rods/R = C if(R.get_amount() < HOLE_REPAIR) to_chat(user, "You need [HOLE_REPAIR] rods to fix this fence!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You begin repairing the fence...") if(do_after(user, 3 SECONDS * C.toolspeed, target = src) && hole_size != NO_HOLE && R.use(HOLE_REPAIR)) playsound(src, C.usesound, 80, 1) @@ -138,8 +138,7 @@ obj_integrity = max_integrity to_chat(user, "You repair the fence.") update_cut_status() - return - . = ..() + return ITEM_INTERACT_COMPLETE /obj/structure/fence/Bumped(atom/user) if(!ismob(user)) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 0c735c95982..5cc1f08153e 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -531,7 +531,7 @@ A.loc = get_turf(src) */ -/obj/structure/bush/attackby__legacy__attackchain(obj/I as obj, mob/user as mob, params) +/obj/structure/bush/item_interaction(mob/living/user, obj/item/I, list/modifiers) //hatchets can clear away undergrowth if(istype(I, /obj/item/hatchet) && !stump) if(indestructable) @@ -554,8 +554,7 @@ pixel_y = rand(-6,6) else qdel(src) - else - return ..() + return ITEM_INTERACT_COMPLETE //Jungle grass diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 3dce7563874..6dd705d67eb 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -47,108 +47,114 @@ if(temp_check >= GIRDER_MELTING_TEMP) take_damage(10) -/obj/structure/girder/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/girder/item_interaction(mob/living/user, obj/item/W, list/modifiers) add_fingerprint(user) if(istype(W, /obj/item/gun/energy/plasmacutter)) to_chat(user, "You start slicing apart the girder...") if(do_after(user, 40 * W.toolspeed, target = src)) if(!src) - return + return ITEM_INTERACT_COMPLETE playsound(loc, W.usesound, 100, 1) to_chat(user, "You slice apart the girder.") refundMetal(metalUsed) qdel(src) + return ITEM_INTERACT_COMPLETE else if(istype(W, /obj/item/pickaxe/drill/diamonddrill)) to_chat(user, "You drill through the girder!") refundMetal(metalUsed) qdel(src) + return ITEM_INTERACT_COMPLETE else if(istype(W, /obj/item/pickaxe/drill/jackhammer)) playsound(loc, W.usesound, 100, 1) to_chat(user, "You disintegrate the girder!") refundMetal(metalUsed) qdel(src) + return ITEM_INTERACT_COMPLETE else if(istype(W, /obj/item/pyro_claws)) playsound(loc, W.usesound, 100, 1) to_chat(user, "You melt the girder!") refundMetal(metalUsed) qdel(src) + return ITEM_INTERACT_COMPLETE else if(istype(W, /obj/item/stack)) if(iswallturf(loc)) to_chat(user, "There is already a wall present!") - return + return ITEM_INTERACT_COMPLETE if(!isfloorturf(loc)) to_chat(user, "A floor must be present to build a false wall!") - return + return ITEM_INTERACT_COMPLETE if(locate(/obj/structure/falsewall) in loc.contents) to_chat(user, "There is already a false wall present!") - return + return ITEM_INTERACT_COMPLETE if(islava(loc)) to_chat(user, "You can't do that while [src] is in lava!") - return + return ITEM_INTERACT_COMPLETE if(istype(W, /obj/item/stack/sheet/runed_metal)) to_chat(user, "You can't seem to make the metal bend.") - return + return ITEM_INTERACT_COMPLETE if(istype(W, /obj/item/stack/sheet/bamboo)) // pending wall resprite(tm) to_chat(user, "The bamboo doesn't seem to fit around the girder.") - return + return ITEM_INTERACT_COMPLETE if(istype(W,/obj/item/stack/rods)) var/obj/item/stack/rods/S = W if(state == GIRDER_DISPLACED) if(S.get_amount() < 5) to_chat(user, "You need at least five rods to create a false wall!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start building a reinforced false wall...") if(do_after(user, 20, target = src)) if(!loc || !S || S.get_amount() < 5) - return + return ITEM_INTERACT_COMPLETE S.use(5) to_chat(user, "You create a false wall. Push on it to open or close the passage.") var/obj/structure/falsewall/iron/FW = new (loc) transfer_fingerprints_to(FW) qdel(src) + return ITEM_INTERACT_COMPLETE else if(S.get_amount() < 5) to_chat(user, "You need at least five rods to add plating!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start adding plating...") if(do_after(user, 40, target = src)) if(!loc || !S || S.get_amount() < 5) - return + return ITEM_INTERACT_COMPLETE S.use(5) to_chat(user, "You add the plating.") var/turf/T = get_turf(src) T.ChangeTurf(/turf/simulated/wall/mineral/iron) transfer_fingerprints_to(T) qdel(src) - return + return ITEM_INTERACT_COMPLETE if(istype(W, /obj/item/stack/ore/glass/basalt)) var/obj/item/stack/ore/glass/basalt/A = W if(state == GIRDER_DISPLACED) if(A.get_amount() < 2) to_chat(user, "You need at least two [A] to create a false wall!") - return + return ITEM_INTERACT_COMPLETE if(do_after(user, 2 SECONDS, target = src)) if(!loc || !A || A.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE A.use(2) to_chat(user, "You create a false wall. Push on it to open or close the passage.") var/obj/structure/falsewall/rock_ancient/FW = new (loc) transfer_fingerprints_to(FW) qdel(src) + return ITEM_INTERACT_COMPLETE else if(A.get_amount() < 2) to_chat(user, "You need at least two [A] to add plating!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start adding [A]...") if(do_after(user, 4 SECONDS, target = src)) if(!src || !A || A.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE A.use(2) to_chat(user, "You add [A].") var/turf/parent_turf = get_turf(src) @@ -156,38 +162,39 @@ for(var/turf/simulated/mineral/X in parent_turf.loc) X.add_hiddenprint(usr) qdel(src) - return + return ITEM_INTERACT_COMPLETE if(!istype(W,/obj/item/stack/sheet)) - return + return ITEM_INTERACT_COMPLETE var/obj/item/stack/sheet/S = W if(!S.wall_allowed) to_chat(user, "You don't think that is good material for a wall!") - return + return ITEM_INTERACT_COMPLETE if(istype(S, /obj/item/stack/sheet/wood)) if(state == GIRDER_DISPLACED) if(S.get_amount() < 2) to_chat(user, "You need two planks of wood to create a false wall!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start building a false wall...") if(do_after(user, 20, target = src)) if(!loc || !S || S.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE S.use(2) to_chat(user, "You create a false wall. Push on it to open or close the passage.") var/obj/structure/falsewall/wood/falsewood = new(loc) transfer_fingerprints_to(falsewood) qdel(src) + return ITEM_INTERACT_COMPLETE else if(S.get_amount() < 2) to_chat(user, "You need two planks of wood to finish a wall!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start adding plating...") if(do_after(user, 40 * W.toolspeed, target = src)) if(!src || !S || S.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE S.use(2) to_chat(user, "You add the plating.") var/turf/Tsrc = get_turf(src) @@ -196,30 +203,30 @@ if(X) X.add_hiddenprint(usr) qdel(src) - return - + return ITEM_INTERACT_COMPLETE else if(istype(S, /obj/item/stack/sheet/metal)) if(state == GIRDER_DISPLACED) if(S.get_amount() < 2) to_chat(user, "You need two sheets of metal to create a false wall!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start building a false wall...") if(do_after(user, 20, target = src)) if(!loc || !S || S.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE S.use(2) to_chat(user, "You create a false wall. Push on it to open or close the passage.") var/obj/structure/falsewall/F = new(loc) transfer_fingerprints_to(F) qdel(src) + return ITEM_INTERACT_COMPLETE else if(S.get_amount() < 2) to_chat(user, "You need two sheets of metal to finish a wall!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start adding plating...") if(do_after(user, 40 * W.toolspeed, target = src)) if(!src || !S || S.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE S.use(2) to_chat(user, "You add the plating.") var/turf/Tsrc = get_turf(src) @@ -228,30 +235,31 @@ if(X) X.add_hiddenprint(usr) qdel(src) - return + return ITEM_INTERACT_COMPLETE if(istype(S, /obj/item/stack/sheet/plasteel)) if(state == GIRDER_DISPLACED) if(S.get_amount() < 2) to_chat(user, "You need at least two sheets to create a false wall!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start building a reinforced false wall...") if(do_after(user, 20, target = src)) if(!loc || !S || S.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE S.use(2) to_chat(user, "You create a reinforced false wall. Push on it to open or close the passage.") var/obj/structure/falsewall/reinforced/FW = new (loc) transfer_fingerprints_to(FW) qdel(src) + return ITEM_INTERACT_COMPLETE else if(state == GIRDER_REINF) if(S.get_amount() < 1) - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start finalizing the reinforced wall...") if(do_after(user, 50, target = src)) if(!src || !S || S.get_amount() < 1) - return + return ITEM_INTERACT_COMPLETE S.use(1) to_chat(user, "You fully reinforce the wall.") var/turf/Tsrc = get_turf(src) @@ -260,44 +268,45 @@ if(X) X.add_hiddenprint(usr) qdel(src) - return + return ITEM_INTERACT_COMPLETE else if(S.get_amount() < 1) - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start reinforcing the girder...") if(do_after(user,60, target = src)) if(!src || !S || S.get_amount() < 1) - return + return ITEM_INTERACT_COMPLETE S.use(1) to_chat(user, "You reinforce the girder.") var/obj/structure/girder/reinforced/R = new (loc) transfer_fingerprints_to(R) qdel(src) - return + return ITEM_INTERACT_COMPLETE if(S.sheettype) var/M = S.sheettype if(state == GIRDER_DISPLACED) if(S.get_amount() < 2) to_chat(user, "You need at least two sheets to create a false wall!") - return + return ITEM_INTERACT_COMPLETE if(do_after(user, 20, target = src)) if(!loc || !S || S.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE S.use(2) to_chat(user, "You create a false wall. Push on it to open or close the passage.") var/F = text2path("/obj/structure/falsewall/[M]") var/obj/structure/FW = new F (loc) transfer_fingerprints_to(FW) qdel(src) + return ITEM_INTERACT_COMPLETE else if(S.get_amount() < 2) to_chat(user, "You need at least two sheets to add plating!") - return + return ITEM_INTERACT_COMPLETE to_chat(user, "You start adding plating...") if(do_after(user,40, target = src)) if(!src || !S || S.get_amount() < 2) - return + return ITEM_INTERACT_COMPLETE S.use(2) to_chat(user, "You add the plating.") var/turf/Tsrc = get_turf(src) @@ -306,12 +315,9 @@ if(X) X.add_hiddenprint(usr) qdel(src) - return - + return ITEM_INTERACT_COMPLETE add_hiddenprint(user) - - else - return ..() + return ITEM_INTERACT_COMPLETE /obj/structure/girder/crowbar_act(mob/user, obj/item/I) if(!can_displace || state != GIRDER_NORMAL) @@ -464,12 +470,13 @@ . = ..() icon_state = GET_CULT_DATA(cult_girder_icon_state, initial(icon_state)) -/obj/structure/girder/cult/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/girder/cult/item_interaction(mob/living/user, obj/item/W, list/modifiers) add_fingerprint(user) if(istype(W, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user)) //Cultists can demolish cult girders instantly with their dagger user.visible_message("[user] strikes [src] with [W]!", "You demolish [src].") refundMetal(metalUsed) qdel(src) + return ITEM_INTERACT_COMPLETE else if(istype(W, /obj/item/gun/energy/plasmacutter)) to_chat(user, "You start slicing apart the girder...") if(do_after(user, 40* W.toolspeed, target = src)) @@ -479,6 +486,7 @@ R.amount = 1 transfer_fingerprints_to(R) qdel(src) + return ITEM_INTERACT_COMPLETE else if(istype(W, /obj/item/pickaxe/drill/jackhammer)) var/obj/item/pickaxe/drill/jackhammer/D = W to_chat(user, "Your jackhammer smashes through the girder!") @@ -487,23 +495,22 @@ transfer_fingerprints_to(R) D.playDigSound() qdel(src) - + return ITEM_INTERACT_COMPLETE else if(istype(W, /obj/item/stack/sheet/runed_metal)) var/obj/item/stack/sheet/runed_metal/R = W if(R.get_amount() < 1) to_chat(user, "You need at least one sheet of runed metal to construct a runed wall!") - return 0 + return ITEM_INTERACT_COMPLETE user.visible_message("[user] begins laying runed metal on [src]...", "You begin constructing a runed wall...") if(do_after(user, 10, target = src)) if(R.get_amount() < 1 || !R) - return + return ITEM_INTERACT_COMPLETE user.visible_message("[user] plates [src] with runed metal.", "You construct a runed wall.") R.use(1) var/turf/T = get_turf(src) T.ChangeTurf(/turf/simulated/wall/cult) qdel(src) - else - return ..() + return ITEM_INTERACT_COMPLETE /obj/structure/girder/cult/narsie_act() return diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index e01e4de3106..4538358f1ac 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -115,20 +115,21 @@ if(pass_info.is_movable) . = . || pass_info.pass_flags & PASSGRILLE -/obj/structure/grille/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/grille/item_interaction(mob/living/user, obj/item/I, list/modifiers) user.changeNext_move(CLICK_CD_MELEE) add_fingerprint(user) if(istype(I, /obj/item/stack/rods) && broken) repair(user, I) + return ITEM_INTERACT_COMPLETE //window placing begin else if(is_glass_sheet(I)) build_window(I, user) - return + return ITEM_INTERACT_COMPLETE //window placing end - else if(istype(I, /obj/item/shard) || !shock(user, 70)) - return ..() + else if((!istype(I, /obj/item/shard)) && shock(user, 70)) + return ITEM_INTERACT_COMPLETE /obj/structure/grille/proc/repair(mob/user, obj/item/stack/rods/R) if(R.get_amount() >= 1) diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index ee55b07cd7d..e8e2fea71ba 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -154,33 +154,29 @@ blade_status = GUILLOTINE_BLADE_DROPPED icon_state = "guillotine" -/obj/structure/guillotine/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/guillotine/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/whetstone)) add_fingerprint(user) if(blade_status == GUILLOTINE_BLADE_SHARPENING) - return + return ITEM_INTERACT_COMPLETE if(blade_status == GUILLOTINE_BLADE_RAISED) if(blade_sharpness < GUILLOTINE_BLADE_MAX_SHARP) blade_status = GUILLOTINE_BLADE_SHARPENING - if(do_after(user, 7, target = src)) + if(do_after(user, W.toolspeed, target = src)) blade_status = GUILLOTINE_BLADE_RAISED user.visible_message("[user] sharpens the large blade of the guillotine.", "You sharpen the large blade of the guillotine.") blade_sharpness += 1 playsound(src, 'sound/items/screwdriver.ogg', 100, 1) - return else blade_status = GUILLOTINE_BLADE_RAISED - return else to_chat(user, "The blade is sharp enough!") - return else to_chat(user, "You need to raise the blade in order to sharpen it!") - return - else - return ..() + + return ITEM_INTERACT_COMPLETE /obj/structure/guillotine/wrench_act(mob/user, obj/item/I) if(current_action) diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 3f9b36a6b38..78b04ded2f4 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -53,7 +53,6 @@ icon_state = "wall" var/torn = /obj/item/inflatable/torn var/intact = /obj/item/inflatable - new_attack_chain = TRUE /obj/structure/inflatable/examine(mob/user) . = ..() @@ -219,7 +218,7 @@ if(!useResource(user)) return ITEM_INTERACT_COMPLETE - + return ..() /obj/item/inflatable/cyborg/proc/useResource(mob/user) diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 5b9a3a9346e..47312248b06 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -8,7 +8,6 @@ density = TRUE face_while_pulling = FALSE container_type = OPENCONTAINER - new_attack_chain = TRUE //copypaste sorry var/maximum_volume = 150 var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 3d782aafc03..1fa497e829b 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -20,7 +20,7 @@ deconstruct(TRUE) return TRUE -/obj/structure/kitchenspike_frame/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/kitchenspike_frame/item_interaction(mob/living/user, obj/item/I, list/modifiers) add_fingerprint(user) if(istype(I, /obj/item/stack/rods)) var/obj/item/stack/rods/R = I @@ -30,9 +30,9 @@ new /obj/structure/kitchenspike(loc) add_fingerprint(user) qdel(src) - return - else - return ..() + return ITEM_INTERACT_COMPLETE + + return ..() /obj/structure/kitchenspike_frame/examine(mob/user) . = ..() @@ -56,6 +56,7 @@ buckle_lying = FALSE can_buckle = TRUE max_integrity = 250 + var/impale_time = 6 SECONDS /obj/structure/kitchenspike/examine(mob/user) . = ..() @@ -69,11 +70,13 @@ else ..() -/obj/structure/kitchenspike/attackby__legacy__attackchain(obj/item/I, mob/user) +/obj/structure/kitchenspike/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/grab)) var/obj/item/grab/G = I if(G.affecting && isliving(G.affecting)) start_spike(G.affecting, user) + return ITEM_INTERACT_COMPLETE + return ..() /obj/structure/kitchenspike/crowbar_act(mob/living/user, obj/item/I) @@ -103,7 +106,7 @@ "[user] tries to slam [victim] onto the meat spike!", "[user] tries to slam you onto the meat spike!" ) - if(do_mob(user, victim, 6 SECONDS)) + if(do_mob(user, victim, impale_time)) end_spike(victim, user) /obj/structure/kitchenspike/proc/end_spike(mob/living/victim, mob/user) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 2abb32aadbf..7ec90313aee 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -28,18 +28,28 @@ /obj/structure/lattice/proc/deconstruction_hints(mob/user) return "The rods look like they could be cut. There's space for more rods or a tile." -/obj/structure/lattice/attackby__legacy__attackchain(obj/item/C, mob/user, params) +/obj/structure/lattice/wirecutter_act(mob/living/user, obj/item/wirecutters/wirecutters) if(resistance_flags & INDESTRUCTIBLE) return - if(istype(C, /obj/item/wirecutters)) - var/obj/item/wirecutters/W = C - playsound(loc, W.usesound, 50, 1) - to_chat(user, "Slicing [name] joints...") - deconstruct() - else - // hand this off to the turf instead (for building plating, catwalks, etc) - var/turf/T = get_turf(src) - return T.item_interaction(user, C, params) + if(!istype(wirecutters)) + return + + playsound(loc, wirecutters.usesound, 50, 1) + to_chat(user, "Slicing [name] joints...") + deconstruct() + + return ITEM_INTERACT_COMPLETE + +/obj/structure/lattice/item_interaction(mob/living/user, obj/item/used, list/modifiers) + // this is still here for historical reasons though it's + // not clear if the original intention was to prevent indestructible + // lattices from e.g. being built over with plating. + if(resistance_flags & INDESTRUCTIBLE) + return + + // hand this off to the turf (for building plating, catwalks, etc) + var/turf/T = get_turf(src) + return T.item_interaction(user, used, modifiers) /obj/structure/lattice/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm index d39d7e97540..4bf4f1d81ce 100644 --- a/code/game/objects/structures/lavaland/necropolis_tendril.dm +++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm @@ -43,8 +43,7 @@ GLOBAL_LIST_EMPTY(tendrils) new /obj/structure/closet/crate/necropolis/tendril(loc) return ..() -/obj/structure/spawner/lavaland/attacked_by__legacy__attackchain(obj/item/I, mob/living/user) - . = ..() +/obj/structure/spawner/lavaland/attacked_by(obj/item/attacker, mob/living/user) SEND_SIGNAL(src, COMSIG_SPAWNER_SET_TARGET, user) /obj/structure/spawner/lavaland/bullet_act(obj/item/projectile/P) diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm index fd0e30d1144..9105d5a5db4 100644 --- a/code/game/objects/structures/loom.dm +++ b/code/game/objects/structures/loom.dm @@ -9,10 +9,14 @@ icon_state = "loom" density = TRUE anchored = TRUE + // TODO: should absolutely be keyed to tool speed but + // is just a constant for now for use in tests + var/disassemble_speed = 5 SECONDS -/obj/structure/loom/attackby__legacy__attackchain(obj/item/I, mob/user) +/obj/structure/loom/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(weave(I, user)) - return + return ITEM_INTERACT_COMPLETE + return ..() /obj/structure/loom/crowbar_act(mob/user, obj/item/I) @@ -20,7 +24,7 @@ if(!I.use_tool(src, user, 0)) return TOOL_ATTEMPT_DISMANTLE_MESSAGE - if(I.use_tool(src, user, 50, volume = I.tool_volume)) + if(I.use_tool(src, user, disassemble_speed, volume = I.tool_volume)) TOOL_DISMANTLE_SUCCESS_MESSAGE deconstruct(disassembled = TRUE) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 64602411892..f4231e421c5 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -116,15 +116,17 @@ else icon_state = initial_state -/obj/structure/mineral_door/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/mineral_door/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/pickaxe)) var/obj/item/pickaxe/digTool = W to_chat(user, "You start digging \the [src].") if(do_after(user, 40 * digTool.toolspeed * hardness, target = src) && src) to_chat(user, "You finished digging.") deconstruct(TRUE) + return ITEM_INTERACT_COMPLETE else if(user.a_intent != INTENT_HARM) attack_hand(user) + return ITEM_INTERACT_COMPLETE else return ..() @@ -182,12 +184,13 @@ sheetType = /obj/item/stack/sheet/mineral/plasma cares_about_temperature = TRUE -/obj/structure/mineral_door/transparent/plasma/attackby__legacy__attackchain(obj/item/W, mob/user) +/obj/structure/mineral_door/transparent/plasma/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(W.get_heat()) message_admins("Plasma mineral door ignited by [key_name_admin(user)] in ([x], [y], [z] - JMP)", 0, 1) log_game("Plasma mineral door ignited by [key_name(user)] in ([x], [y], [z])") investigate_log("was ignited by [key_name(user)]",INVESTIGATE_ATMOS) TemperatureAct(100) + return ITEM_INTERACT_COMPLETE else return ..() diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index eeea74eaeb6..1e01adef4b7 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -106,6 +106,10 @@ var/organ_warn = FALSE var/actually_magical = TRUE +/obj/structure/mirror/magic/Initialize(mapload, newdir, building) + . = ..() + RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by)) + /obj/structure/mirror/magic/attack_hand(mob/user) if(!ishuman(user) || broken) return @@ -174,9 +178,6 @@ /obj/structure/mirror/magic/ui_close(mob/user) curse(user) -/obj/structure/mirror/magic/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - return - /obj/structure/mirror/magic/proc/curse(mob/living/user) return diff --git a/code/game/objects/structures/misc_structures.dm b/code/game/objects/structures/misc_structures.dm index fa7ff2c335b..f0387c9e570 100644 --- a/code/game/objects/structures/misc_structures.dm +++ b/code/game/objects/structures/misc_structures.dm @@ -10,7 +10,6 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "signpost" anchored = TRUE - new_attack_chain = TRUE var/writing = "" /obj/structure/signpost/Initialize(mapload) diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index 13faf7fd874..e1b990d3438 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -6,7 +6,6 @@ density = TRUE container_type = OPENCONTAINER face_while_pulling = FALSE - new_attack_chain = TRUE var/obj/item/mop/stored_mop = null var/maximum_volume = 150 var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite @@ -39,7 +38,7 @@ /obj/structure/mopbucket/proc/handle_mop_interaction(mob/living/user, obj/item/used) if(!istype(used, /obj/item/mop)) return FALSE - + . = TRUE var/robot_mop = used.is_robot_module() var/obj/item/mop/attacking_mop = used diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 94f5f3f02e9..85de7d134d4 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -37,7 +37,6 @@ anchored = TRUE var/open_sound = 'sound/items/deconstruct.ogg' var/status - new_attack_chain = TRUE /obj/structure/morgue/Initialize(mapload) . = ..() @@ -338,7 +337,6 @@ GLOBAL_LIST_EMPTY(crematoriums) var/repairstate = CREMATOR_OPERATIONAL // Repairstate 0 is DESTROYED, 1 has the igniter applied but needs welding (IN_REPAIR), 2 is OPERATIONAL var/locked = FALSE var/open_sound = 'sound/items/deconstruct.ogg' - new_attack_chain = TRUE /obj/structure/crematorium/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index c7edc835230..67d21107983 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -103,20 +103,20 @@ paper.show_content(usr) return -/obj/structure/noticeboard/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/noticeboard/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/paper)) if(notices >= MAX_NOTICES) to_chat(user, "You reach to pin your paper to the board but hesitate. You are certain your paper will not be seen among the many others already attached.") - return + return ITEM_INTERACT_COMPLETE if(!user.drop_item()) - return + return ITEM_INTERACT_COMPLETE I.forceMove(src) notices++ to_chat(user, "You pin the paper to the noticeboard.") update_icon(UPDATE_ICON_STATE) add_fingerprint(user) SStgui.update_uis(src) - return + return ITEM_INTERACT_COMPLETE return ..() diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index 7b3075310e7..27e8ff37ca1 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -43,9 +43,9 @@ /obj/structure/railing/cap/reversed icon_state = "railing_cap_reversed" -/obj/structure/railing/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) - ..() - add_fingerprint(user) +/obj/structure/railing/item_interaction(mob/living/user, obj/item/used, list/modifiers) + . = ..() + add_fingerprint(user) // No clue why this is happening here /obj/structure/railing/attack_animal(mob/living/simple_animal/M) . = ..() diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index 889c6a970a1..92ce2edecc2 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -39,8 +39,8 @@ new_dir = 0 return -1 - -/obj/structure/reflector/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/reflector/item_interaction(mob/living/user, obj/item/W, list/modifiers) + . = ITEM_INTERACT_COMPLETE //Finishing the frame if(istype(W,/obj/item/stack/sheet)) if(finished) diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 430584fb87d..da5949c0a85 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -187,30 +187,33 @@ GLOBAL_LIST_EMPTY(safes) else ui_interact(user) -/obj/structure/safe/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/safe/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(open) if(I.flags && ABSTRACT) - return + return ITEM_INTERACT_COMPLETE if(broken && istype(I, /obj/item/safe_internals) && do_after(user, 2 SECONDS, target = src)) to_chat(user, "You replace the broken mechanism.") qdel(I) broken = FALSE locked = FALSE update_icon() + return ITEM_INTERACT_COMPLETE else if(I.w_class + space <= maxspace) if(!user.drop_item()) to_chat(user, "\The [I] is stuck to your hand, you cannot put it in the safe!") - return + return ITEM_INTERACT_COMPLETE space += I.w_class I.forceMove(src) to_chat(user, "You put [I] in [src].") SStgui.update_uis(src) + return ITEM_INTERACT_COMPLETE else to_chat(user, "[I] won't fit in [src].") + return ITEM_INTERACT_COMPLETE else if(istype(I, /obj/item/clothing/neck/stethoscope)) attack_hand(user) - return + return ITEM_INTERACT_COMPLETE else if(istype(I, /obj/item/thermal_drill)) if(drill) to_chat(user, "There is already a drill attached!") @@ -222,9 +225,10 @@ GLOBAL_LIST_EMPTY(safes) drill = I time_to_drill = DRILL_TIME * drill.time_multiplier update_icon() + return ITEM_INTERACT_COMPLETE else to_chat(user, "You can't put [I] into the safe while it is closed!") - return + return ITEM_INTERACT_COMPLETE /obj/structure/safe/ui_state(mob/user) return GLOB.physical_state diff --git a/code/game/objects/structures/shelves.dm b/code/game/objects/structures/shelves.dm index 367ee254ed6..da3459403b4 100644 --- a/code/game/objects/structures/shelves.dm +++ b/code/game/objects/structures/shelves.dm @@ -27,7 +27,7 @@ GLOBAL_LIST_INIT(shelf_colors, list("basic", "sci", "sup", "serv", "med", "sec", if(mapload) SEND_SIGNAL(src, COMSIG_SHELF_ADDED_ON_MAPLOAD) -/obj/structure/shelf/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) +/obj/structure/shelf/item_interaction(mob/living/user, obj/item/I, list/modifiers) var/obj/item/toy/crayon/spraycan/spraycan = I if(!istype(spraycan)) return ..() @@ -41,7 +41,7 @@ GLOBAL_LIST_INIT(shelf_colors, list("basic", "sci", "sup", "serv", "med", "sec", if(!COOLDOWN_FINISHED(src, spraypaint_cd)) to_chat(user, "The paint on [src] is still drying!") - return + return ITEM_INTERACT_COMPLETE var/cur_idx = GLOB.shelf_colors.Find(shelf_style) if(!cur_idx) @@ -54,6 +54,7 @@ GLOBAL_LIST_INIT(shelf_colors, list("basic", "sci", "sup", "serv", "med", "sec", // Tiny cooldown to prevent constant spamming of the action COOLDOWN_START(src, spraypaint_cd, 1 SECONDS) + return ITEM_INTERACT_COMPLETE /obj/structure/shelf/proc/set_style(new_style) if(shelf_style == new_style && !isnull(shelf_overlay)) @@ -73,7 +74,7 @@ GLOBAL_LIST_INIT(shelf_colors, list("basic", "sci", "sup", "serv", "med", "sec", . = TRUE if(user.a_intent == INTENT_HELP) return FALSE - if(!I.use_tool(src, user, 2.5 SECONDS, volume = I.tool_volume)) + if(!I.use_tool(src, user, (2.5 SECONDS) * I.toolspeed, volume = I.tool_volume)) return to_chat(user, "You disassemble [src].") diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 0de8b0cee74..195d6e21a04 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -8,11 +8,11 @@ var/oreAmount = 5 var/material_drop_type = /obj/item/stack/sheet/metal -/obj/structure/statue/attackby__legacy__attackchain(obj/item/W, mob/living/user, params) +/obj/structure/statue/item_interaction(mob/living/user, obj/item/W, list/modifiers) add_fingerprint(user) if(!(flags & NODECONSTRUCT)) if(default_unfasten_wrench(user, W)) - return + return ITEM_INTERACT_COMPLETE if(istype(W, /obj/item/gun/energy/plasmacutter)) playsound(src, W.usesound, 100, 1) user.visible_message("[user] is slicing apart the [name]...", \ @@ -23,7 +23,7 @@ user.visible_message("[user] slices apart the [name].", \ "You slice apart the [name].") deconstruct(TRUE) - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/statue/welder_act(mob/user, obj/item/I) @@ -107,13 +107,13 @@ PlasmaBurn() ..() -/obj/structure/statue/plasma/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/statue/plasma/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(W.get_heat() > 300)//If the temperature of the object is over 300, then ignite message_admins("[key_name_admin(user)] ignited a plasma statue at [COORD(loc)]") log_game("[key_name(user)] ignited plasma a statue at [COORD(loc)]") investigate_log("[key_name(user)] ignited a plasma statue at [COORD(loc)]", INVESTIGATE_ATMOS) ignite(W.get_heat()) - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/statue/plasma/welder_act(mob/user, obj/item/I) @@ -225,7 +225,7 @@ honk() ..() -/obj/structure/statue/bananium/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/statue/bananium/item_interaction(mob/living/user, obj/item/used, list/modifiers) honk() return ..() @@ -321,11 +321,12 @@ new /obj/item/grown/log(drop_location()) return ..() -/obj/structure/snowman/built/attackby__legacy__attackchain(obj/item/I, mob/user) +/obj/structure/snowman/built/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/snowball) && obj_integrity < max_integrity) to_chat(user, "You patch some of the damage on [src] with [I].") obj_integrity = max_integrity qdel(I) + return ITEM_INTERACT_COMPLETE else return ..() diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 698d29a04c0..b65bd249f8b 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -151,7 +151,7 @@ var/icon_down = "down" var/folded = /obj/item/roller -/obj/structure/bed/roller/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/bed/roller/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/roller_holder)) if(has_buckled_mobs()) if(length(buckled_mobs) > 1) @@ -163,6 +163,8 @@ user.visible_message("[user] collapses \the [name].", "You collapse \the [name].") new folded(get_turf(src)) qdel(src) + + return ITEM_INTERACT_COMPLETE else return ..() diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index be7597fe0c0..5e6eae29ff8 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -35,12 +35,12 @@ W.setDir(dir) qdel(src) -/obj/structure/chair/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/structure/chair/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/assembly/shock_kit)) var/obj/item/assembly/shock_kit/SK = W if(!SK.status) to_chat(user, "[SK] is not ready to be attached!") - return + return ITEM_INTERACT_COMPLETE user.drop_item() var/obj/structure/chair/e_chair/E = new /obj/structure/chair/e_chair(get_turf(src), SK) playsound(src.loc, W.usesound, 50, 1) @@ -48,8 +48,7 @@ SK.loc = E SK.master = E qdel(src) - return - return ..() + return ITEM_INTERACT_COMPLETE /obj/structure/chair/wrench_act(mob/user, obj/item/I) . = TRUE @@ -322,8 +321,7 @@ armrest.layer = ABOVE_MOB_LAYER return ..() -/obj/structure/chair/sofa/attacked_by__legacy__attackchain(obj/item/I, mob/living/user) - . = ..() +/obj/structure/chair/sofa/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(!colorable) return if(istype(I, /obj/item/toy/crayon)) @@ -332,11 +330,17 @@ var/list/hsl = rgb2hsl(hex2num(copytext(new_color, 2, 4)), hex2num(copytext(new_color, 4, 6)), hex2num(copytext(new_color, 6, 8))) hsl[3] = max(hsl[3], 0.4) var/list/rgb = hsl2rgb(arglist(hsl)) - color = "#[num2hex(rgb[1], 2)][num2hex(rgb[2], 2)][num2hex(rgb[3], 2)]" - if(color) - cut_overlay(armrest) - armrest = GetArmrest() - update_armrest() + set_color("#[num2hex(rgb[1], 2)][num2hex(rgb[2], 2)][num2hex(rgb[3], 2)]") + return ITEM_INTERACT_COMPLETE + +/obj/structure/chair/sofa/proc/set_color(new_color) + if(color == new_color) + return + + color = new_color + cut_overlay(armrest) + armrest = GetArmrest() + update_armrest() /obj/structure/chair/sofa/proc/GetArmrest() return mutable_appearance('icons/obj/chairs.dmi', "[icon_state]_armrest") @@ -437,13 +441,17 @@ /obj/structure/chair/sofa/bench/handle_layer() return -/obj/structure/chair/sofa/bench/attacked_by__legacy__attackchain(obj/item/I, mob/living/user) - . = ..() +/obj/structure/chair/sofa/bench/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/toy/crayon)) var/obj/item/toy/crayon/C = I - cover_color = C.colour - if(cover_color) - GetCover() + set_cover_color(C.colour) + return ITEM_INTERACT_COMPLETE + +/obj/structure/chair/sofa/bench/proc/set_cover_color(new_color) + if(cover_color == new_color) + return + + GetCover() /obj/structure/chair/sofa/bench/left icon_state = "bench_left_mapping" diff --git a/code/game/objects/structures/table_frames.dm b/code/game/objects/structures/table_frames.dm index ee8ccf014d0..e4f1036a225 100644 --- a/code/game/objects/structures/table_frames.dm +++ b/code/game/objects/structures/table_frames.dm @@ -24,9 +24,11 @@ ///What stacks can be used to make the table, and if it will result in a unique table var/list/restrict_table_types = list() //ex: list(/obj/item/stack/tile/carpet = /obj/structure/table/wood/poker, /obj/item/stack/sheet/wood = /obj/item/stack/sheet/wood::table_type), carpet will make poker table, wood will result in standard table_type. If the list is empty, any material can be used for its default table_type. -/obj/structure/table_frame/attackby__legacy__attackchain(obj/item/I, mob/user, params) - if(!try_make_table(I, user)) - return ..() +/obj/structure/table_frame/item_interaction(mob/living/user, obj/item/I, list/modifiers) + if(try_make_table(I, user)) + return ITEM_INTERACT_COMPLETE + + return ..() ///Try to make a table with the item used to attack. FALSE if you can't make a table and should attack. TRUE does not necessarily mean a table was made. /obj/structure/table_frame/proc/try_make_table(obj/item/stack/stack, mob/user) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 8dc548e7be8..22efeb134a2 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -227,30 +227,30 @@ return TRUE qdel(G) -/obj/structure/table/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/table/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/grab)) tablepush(I, user) - return + return ITEM_INTERACT_COMPLETE if(isrobot(user) && !istype(I.loc, /obj/item/gripper)) - return + return ITEM_INTERACT_COMPLETE if(user.a_intent == INTENT_HELP && !(I.flags & ABSTRACT)) if(user.drop_item()) I.Move(loc) - var/list/click_params = params2list(params) //Center the icon where the user clicked. - if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + if(!modifiers || !modifiers["icon-x"] || !modifiers["icon-y"]) return //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - I.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) - I.pixel_y = clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_x = clamp(text2num(modifiers["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + I.pixel_y = clamp(text2num(modifiers["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) if(slippery) step_away(I, user) visible_message("[I] slips right off [src]!") playsound(loc, 'sound/misc/slip.ogg', 50, TRUE, -1) else //Don't want slippery moving tables to have the item attached to them if it slides off. item_placed(I) + return ITEM_INTERACT_COMPLETE else return ..() @@ -944,15 +944,15 @@ step(O, get_dir(O, src)) return TRUE -/obj/structure/rack/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/rack/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(isrobot(user) && !istype(W.loc, /obj/item/gripper)) return if(user.a_intent == INTENT_HARM) - return ..() + return if(!(W.flags & ABSTRACT)) if(user.drop_item()) W.Move(loc) - return + return ITEM_INTERACT_COMPLETE /obj/structure/rack/wrench_act(mob/user, obj/item/I) . = TRUE diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index e86d23a5d35..a5958cc4bfe 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -95,14 +95,14 @@ add_fingerprint(usr) return TRUE -/obj/structure/dispenser/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/dispenser/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/tank/internals/oxygen) || istype(I, /obj/item/tank/internals/air) || istype(I, /obj/item/tank/internals/anesthetic)) try_insert_tank(user, stored_oxygen_tanks, I) - return + return ITEM_INTERACT_COMPLETE if(istype(I, /obj/item/tank/internals/plasma)) try_insert_tank(user, stored_plasma_tanks, I) - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/dispenser/wrench_act(mob/living/user, obj/item/I) diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index 625a8a8ba91..f9da361036b 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -22,7 +22,7 @@ pinned_target = null density = TRUE -/obj/structure/target_stake/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/target_stake/item_interaction(mob/living/user, obj/item/W, list/modifiers) // Putting objects on the stake. Most importantly, targets if(istype(W, /obj/item/target) && !pinned_target) density = FALSE @@ -32,7 +32,7 @@ W.layer = 3.1 pinned_target = W to_chat(user, "You slide the target into the stake.") - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/target_stake/attack_hand(mob/user) diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index 8c9f729d30b..ae290e549d2 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -103,7 +103,7 @@ L.Weaken(10 SECONDS) -/obj/structure/transit_tube/station/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/transit_tube/station/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/grab) && hatch_state == TRANSIT_TUBE_OPEN) var/obj/item/grab/G = W if(ismob(G.affecting) && G.state >= GRAB_AGGRESSIVE) @@ -115,6 +115,7 @@ Bumped(GM) qdel(G) break + return ITEM_INTERACT_COMPLETE /obj/structure/transit_tube/station/proc/open_hatch() if(hatch_state == TRANSIT_TUBE_CLOSED) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 8d24c2bb9fb..f40be4798b9 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -10,7 +10,6 @@ var/cistern = FALSE //if the cistern bit is open var/w_items = 0 //the combined w_class of all the items in the cistern var/mob/living/swirlie = null //the mob being given a swirlie - new_attack_chain = TRUE MAPPING_DIRECTIONAL_HELPERS_CUSTOM(/obj/structure/toilet, 8, -8, 0, 0) @@ -237,7 +236,6 @@ MAPPING_DIRECTIONAL_HELPERS_CUSTOM(/obj/structure/toilet, 8, -8, 0, 0) icon = 'icons/obj/watercloset.dmi' icon_state = "urinal" anchored = TRUE - new_attack_chain = TRUE /obj/structure/urinal/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(istype(used, /obj/item/grab)) @@ -520,7 +518,6 @@ MAPPING_DIRECTIONAL_HELPERS_CUSTOM(/obj/machinery/shower, 16, -5, 0, 0) desc = "A sink used for washing one's hands and face." anchored = TRUE var/sink_flags = SINK_MOVEABLE - new_attack_chain = TRUE MAPPING_DIRECTIONAL_HELPERS_CUSTOM(/obj/structure/sink, 18, -4, 0, 0) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 9177012a378..5a3c261d1a1 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -106,9 +106,10 @@ if(direction == dir && density) return COMPONENT_ATOM_BLOCK_EXIT -/obj/structure/windoor_assembly/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/windoor_assembly/item_interaction(mob/living/user, obj/item/W, list/modifiers) //I really should have spread this out across more states but thin little windoors are hard to sprite. add_fingerprint(user) + . = ITEM_INTERACT_COMPLETE switch(state) if(EMPTY_ASSEMBLY) //Adding plasteel makes the assembly a secure windoor assembly. Step 2 (optional) complete. diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 22f2d6ffe88..2fdf19146a8 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -213,9 +213,10 @@ deconstruct(FALSE) attacker.visible_message("[attacker] smashes through [src]!", "You smash through [src].", "You hear glass breaking.") -/obj/structure/window/attackby__legacy__attackchain(obj/item/I, mob/living/user, params) +/obj/structure/window/item_interaction(mob/living/user, obj/item/I, list/modifiers) + . = ITEM_INTERACT_COMPLETE if(!can_be_reached(user)) - return 1 //skip the afterattack + return add_fingerprint(user) if(istype(I, /obj/item/stack/rods) && user.a_intent == INTENT_HELP) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index d28b16731bb..5e275530623 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -550,7 +550,7 @@ var/obj/item/stack/cable_coil/C = used for(var/obj/structure/cable/LC in src) if(LC.d1 == 0 || LC.d2 == 0) - LC.attackby__legacy__attackchain(C, user) + LC.item_interaction(user, C) return ITEM_INTERACT_COMPLETE C.place_turf(src, user) return ITEM_INTERACT_COMPLETE @@ -559,7 +559,7 @@ if(R.loaded) for(var/obj/structure/cable/LC in src) if(LC.d1 == 0 || LC.d2 == 0) - LC.attackby__legacy__attackchain(R, user) + LC.item_interaction(user, R) return ITEM_INTERACT_COMPLETE R.loaded.place_turf(src, user) R.is_empty(user) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 50fd19bdadc..508819fde29 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -482,7 +482,7 @@ eater.say("Nom") wither() -/obj/structure/spacevine/attacked_by__legacy__attackchain(obj/item/I, mob/living/user) +/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user) var/damage_dealt = I.force if(istype(I, /obj/item/scythe)) var/obj/item/scythe/S = I diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index c24397bb2fb..f3c10dbcf64 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -146,7 +146,8 @@ . += "there's no room for more honeycomb!" -/obj/structure/beebox/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/beebox/item_interaction(mob/living/user, obj/item/I, list/modifiers) + . = ITEM_INTERACT_COMPLETE if(istype(I, /obj/item/honey_frame)) var/obj/item/honey_frame/HF = I if(length(honey_frames) < BEEBOX_MAX_FRAMES) diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm index 6f662730ea6..1147a39812e 100644 --- a/code/modules/hydroponics/fermenting_barrel.dm +++ b/code/modules/hydroponics/fermenting_barrel.dm @@ -38,22 +38,21 @@ qdel(G) playsound(src, 'sound/effects/bubbles.ogg', 50, TRUE) -/obj/structure/fermenting_barrel/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/fermenting_barrel/item_interaction(mob/living/user, obj/item/I, list/modifiers) var/obj/item/food/grown/G = I if(istype(G)) if(!G.can_distill) to_chat(user, "You can't distill this into anything...") - return FALSE + return ITEM_INTERACT_COMPLETE else if(!user.drop_item()) to_chat(user, "[G] is stuck to your hand!") - return FALSE + return ITEM_INTERACT_COMPLETE G.forceMove(src) to_chat(user, "You place [G] into [src] to start the fermentation process.") addtimer(CALLBACK(src, PROC_REF(makeWine), G), rand(80, 120) * speed_multiplier) - else if(I.is_refillable()) - return FALSE // To refill via afterattack proc - else - return ..() + return ITEM_INTERACT_COMPLETE + + return ..() /obj/structure/fermenting_barrel/attack_hand(mob/user) open = !open diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index fd0e12b9cd6..c2e8397b803 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -129,7 +129,6 @@ var/light_strength = 6 light_color = "#ED9200" anchored = TRUE - new_attack_chain = TRUE /obj/structure/lightable/proc/CheckOxygen() var/turf/T = get_turf(src) diff --git a/code/modules/library/library_equipment.dm b/code/modules/library/library_equipment.dm index 935c91b656a..8a6e91ea7fc 100644 --- a/code/modules/library/library_equipment.dm +++ b/code/modules/library/library_equipment.dm @@ -39,13 +39,13 @@ I.forceMove(src) update_icon(UPDATE_OVERLAYS) -/obj/structure/bookcase/attackby__legacy__attackchain(obj/item/O, mob/user) +/obj/structure/bookcase/item_interaction(mob/living/user, obj/item/O, list/modifiers) if(is_type_in_list(O, allowed_books)) if(!user.drop_item()) - return + return ITEM_INTERACT_COMPLETE O.forceMove(src) update_icon(UPDATE_OVERLAYS) - return TRUE + return ITEM_INTERACT_COMPLETE if(istype(O, /obj/item/storage/bag/books)) var/obj/item/storage/bag/books/B = O for(var/obj/item/T in B.contents) @@ -53,10 +53,10 @@ B.remove_from_storage(T, src) to_chat(user, "You empty [O] into [src].") update_icon(UPDATE_OVERLAYS) - return TRUE + return ITEM_INTERACT_COMPLETE if(is_pen(O)) rename_interactive(user, O) - return TRUE + return ITEM_INTERACT_COMPLETE return ..() diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index aeb81165663..e5a505da8e0 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -39,11 +39,11 @@ else return ..() -/obj/structure/closet/crate/secure/loot/attackby__legacy__attackchain(obj/item/W, mob/user) +/obj/structure/closet/crate/secure/loot/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(locked) if(istype(W, /obj/item/card/emag)) boom(user) - return 1 + return ITEM_INTERACT_COMPLETE if(istype(W, /obj/item/multitool)) to_chat(user, "DECA-CODE LOCK REPORT:") if(attempts == 1) @@ -67,7 +67,8 @@ ++cows to_chat(user, "Last code attempt had [bulls] correct digits at correct positions and [cows] correct digits at incorrect positions.") - return 1 + return ITEM_INTERACT_COMPLETE + return ..() /obj/structure/closet/crate/secure/loot/emag_act(mob/user) diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index e482243b6e9..b56c1aab579 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -125,7 +125,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) qdel(src) -/obj/structure/marker_beacon/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/marker_beacon/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/stack/marker_beacon)) var/obj/item/stack/marker_beacon/M = I to_chat(user, "You start picking [src] up...") @@ -133,7 +133,8 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( M.add(1) playsound(src, 'sound/items/deconstruct.ogg', 50, 1) qdel(src) - return + + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/marker_beacon/AltClick(mob/living/user) @@ -154,11 +155,9 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( base_icon_state = "dockingmarker" flags = NODECONSTRUCT -/obj/structure/marker_beacon/dock_marker/update_icon_state() - set_light(light_range, light_power, LIGHT_COLOR_BLUE) - -/obj/structure/marker_beacon/dock_marker/attackby__legacy__attackchain() - return +/obj/structure/marker_beacon/dock_marker/Initialize(mapload, set_color) + . = ..() + RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by)) /obj/structure/marker_beacon/dock_marker/attack_hand() return diff --git a/code/modules/mining/gravestones.dm b/code/modules/mining/gravestones.dm index 816a5edc43f..c686f9d5d69 100644 --- a/code/modules/mining/gravestones.dm +++ b/code/modules/mining/gravestones.dm @@ -6,7 +6,6 @@ icon_state = "grave_basalt_open" anchored = TRUE layer = BELOW_OBJ_LAYER - new_attack_chain = TRUE /// What does the grave contain? var/atom/buried /// What does the headstone say? diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index fb5b67dc397..6d9d74797bd 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -60,13 +60,15 @@ desc = initial(desc) harvested = FALSE -/obj/structure/flora/ash/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/flora/ash/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(!harvested && needs_sharp_harvest && W.sharp) user.visible_message("[user] starts to harvest from [src] with [W].","You begin to harvest from [src] with [W].") if(do_after(user, harvest_time, target = src)) harvest(user) - else - return ..() + + return ITEM_INTERACT_COMPLETE + + return ..() /obj/structure/flora/ash/attack_hand(mob/user) if(!harvested && !needs_sharp_harvest) diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 88b454e0037..b4ca1a1e92b 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -9,11 +9,11 @@ density = TRUE pressure_resistance = 5 * ONE_ATMOSPHERE -/obj/structure/ore_box/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/ore_box/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(istype(W, /obj/item/stack/ore)) - if(!user.drop_item()) - return - W.forceMove(src) + if(user.drop_item()) + W.forceMove(src) + return ITEM_INTERACT_COMPLETE else if(isstorage(W)) var/obj/item/storage/S = W S.hide_from(user) @@ -21,6 +21,7 @@ for(var/obj/item/stack/ore/O in S.contents) S.remove_from_storage(O, src) //This will move the item to this item's contents to_chat(user, "You empty the satchel into the box.") + return ITEM_INTERACT_COMPLETE else return ..() diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 65a0c204701..f68b88dc320 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -764,12 +764,9 @@ cloth_golem = null qdel(src) -/obj/structure/cloth_pile/attackby__legacy__attackchain(obj/item/P, mob/living/carbon/human/user, params) - . = ..() - - if(resistance_flags & ON_FIRE) - return - - if(P.get_heat()) +/obj/structure/cloth_pile/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(!(resistance_flags & ON_FIRE) && used.get_heat()) visible_message("[src] bursts into flames!") fire_act() + return ITEM_INTERACT_COMPLETE + diff --git a/code/modules/mob/living/simple_animal/hostile/mining/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining/elites/elite.dm index e902959a88e..9a8995b76ce 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/elites/elite.dm @@ -296,16 +296,15 @@ While using this makes the system rely on OnFire, it still gives options for tim var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(mychild)) H.color = "#FF0000" -/obj/structure/elite_tumor/attackby__legacy__attackchain(obj/item/attacking_item, mob/user, params) - . = ..() - if(istype(attacking_item, /obj/item/organ/internal/regenerative_core) && activity == TUMOR_INACTIVE && !boosted) - var/obj/item/organ/internal/regenerative_core/core = attacking_item +/obj/structure/elite_tumor/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(istype(used, /obj/item/organ/internal/regenerative_core) && activity == TUMOR_INACTIVE && !boosted) + var/obj/item/organ/internal/regenerative_core/core = used visible_message("As [user] drops the core into [src], [src] appears to swell.") icon_state = "advanced_tumor" boosted = TRUE set_light(6) qdel(core) - return TRUE + return ITEM_INTERACT_COMPLETE /obj/structure/elite_tumor/examine(mob/user) . = ..() diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 59ef06398be..52bdf4bb76f 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -186,7 +186,8 @@ hud.screen_loc = UI_RHAND else hud.screen_loc = UI_LHAND - assailant.client.screen += hud + if(assailant.client) + assailant.client.screen += hud /obj/item/grab/process() if(!confirm()) diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index c62730cbde1..85ae2fd67b6 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -44,12 +44,12 @@ I.loc = src -/obj/structure/filingcabinet/attackby__legacy__attackchain(obj/item/O, mob/user, params) +/obj/structure/filingcabinet/item_interaction(mob/living/user, obj/item/O, list/modifiers) if(insert(O, user)) - return + return ITEM_INTERACT_COMPLETE if(user.a_intent != INTENT_HARM) to_chat(user, "You can't put [O.name] in [src]!") - return + return ITEM_INTERACT_COMPLETE return ..() /obj/structure/filingcabinet/wrench_act(mob/living/user, obj/item/I) diff --git a/code/modules/power/cables/cable.dm b/code/modules/power/cables/cable.dm index 2f878445e71..227deb40929 100644 --- a/code/modules/power/cables/cable.dm +++ b/code/modules/power/cables/cable.dm @@ -83,7 +83,8 @@ By design, d1 is the smallest direction and d2 is the highest // - Cable coil : merge cables // - Multitool : get the power currently passing through the cable // -/obj/structure/cable/attackby__legacy__attackchain(obj/item/W, mob/user) +/obj/structure/cable/item_interaction(mob/living/user, obj/item/W, list/modifiers) + . = ITEM_INTERACT_COMPLETE var/turf/T = get_turf(src) if(T.transparent_floor || T.intact) to_chat(user, "You can't interact with something that's under the floor!") 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 c3f182a9d47..59336d0b51d 100644 --- a/code/modules/power/engines/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/engines/singularity/particle_accelerator/particle_accelerator.dm @@ -163,7 +163,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin return 1 return 0 -/obj/structure/particle_accelerator/attackby__legacy__attackchain(obj/item/W, mob/user, params) +/obj/structure/particle_accelerator/item_interaction(mob/living/user, obj/item/W, list/modifiers) if(!iscoil(W)) return ..() if(construction_state == ACCELERATOR_WRENCHED) @@ -174,6 +174,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin "You add some wires.") construction_state = ACCELERATOR_WIRED update_icon() + return ITEM_INTERACT_COMPLETE /obj/structure/particle_accelerator/screwdriver_act(mob/user, obj/item/I) if(construction_state != ACCELERATOR_WIRED && construction_state != ACCELERATOR_READY) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index b0592986cd9..9766fc9411f 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -24,7 +24,7 @@ if(tank_volume && (damage_flag == BULLET || damage_flag == LASER)) boom(FALSE, TRUE) -/obj/structure/reagent_dispensers/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/reagent_dispensers/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(I.is_refillable()) return FALSE //so we can refill them via their afterattack. return ..() @@ -176,11 +176,11 @@ lastrigger = null overlays.Cut() -/obj/structure/reagent_dispensers/fueltank/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/reagent_dispensers/fueltank/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(istype(I, /obj/item/assembly_holder) && accepts_rig) if(rig) to_chat(user, "There is another device in the way.") - return ..() + return ITEM_INTERACT_COMPLETE user.visible_message("[user] begins rigging [I] to [src].", "You begin rigging [I] to [src]") if(do_after(user, 20, target = src)) user.visible_message("[user] rigs [I] to [src].", "You rig [I] to [src].") @@ -199,6 +199,7 @@ test.Shift(NORTH, 1) test.Shift(EAST, 6) overlays += test + return ITEM_INTERACT_COMPLETE else return ..() @@ -299,8 +300,7 @@ /// If TRUE, prevents the player from inserting the disk again while it is currently exploding. var/exploding = FALSE -/obj/structure/reagent_dispensers/beerkeg/nuke/attackby__legacy__attackchain(obj/item/O, mob/user, params) - . = ..() +/obj/structure/reagent_dispensers/beerkeg/nuke/item_interaction(mob/living/user, obj/item/O, list/modifiers) if(exploding) return if(!istype(O, /obj/item/disk/nuclear)) @@ -311,6 +311,7 @@ playsound(src, 'sound/machines/alarm.ogg', 100, FALSE, 0) exploding = TRUE addtimer(CALLBACK(src, PROC_REF(explode)), 13 SECONDS) + return ITEM_INTERACT_COMPLETE /obj/structure/reagent_dispensers/beerkeg/nuke/proc/explode() var/datum/reagents/R = new(100) diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 1877794ac40..6b56546b6f6 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -139,11 +139,11 @@ var/ispipe = is_pipe() var/nicetype = get_nice_name() var/turf/T = get_turf(src) - + if(T.intact) to_chat(user, "You can only attach the [nicetype] if the floor plating is removed.") return - + if(ispipe) anchored = !anchored level = anchored ? 1 : 2 @@ -184,7 +184,8 @@ nicetype = "sorting pipe" return nicetype -/obj/structure/disposalconstruct/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/disposalconstruct/item_interaction(mob/living/user, obj/item/I, list/modifiers) + . = ITEM_INTERACT_COMPLETE var/nicetype = get_nice_name() var/ispipe = is_pipe() // Indicates if we should change the level of this pipe var/turf/T = get_turf(src) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 4e35c1efc60..88545327e74 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -1043,11 +1043,11 @@ //attack by item //weldingtool: unfasten and convert to obj/disposalconstruct -/obj/structure/disposalpipe/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/disposalpipe/item_interaction(mob/living/user, obj/item/used, list/modifiers) var/turf/T = get_turf(src) if(T.intact || T.transparent_floor) to_chat(user, "You can't interact with something that's under the floor!") - return // prevent interaction with T-scanner revealed pipes and pipes under glass + return ITEM_INTERACT_COMPLETE // prevent interaction with T-scanner revealed pipes and pipes under glass add_fingerprint(user) @@ -1221,9 +1221,9 @@ if(mapping_fail) stack_trace("[src] mapped incorrectly at [x],[y],[z] - [mapping_fail]") -/obj/structure/disposalpipe/sortjunction/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/disposalpipe/sortjunction/item_interaction(mob/living/user, obj/item/I, list/modifiers) if(..()) - return + return ITEM_INTERACT_COMPLETE if(istype(I, /obj/item/dest_tagger)) var/obj/item/dest_tagger/O = I @@ -1244,6 +1244,7 @@ sort_type.Add(O.currTag) to_chat(user, "Added [tag] to filter.") update_appearance(UPDATE_NAME|UPDATE_DESC) + return ITEM_INTERACT_COMPLETE /obj/structure/disposalpipe/sortjunction/update_name() . = ..() @@ -1423,18 +1424,18 @@ linked = D D.linkedtrunk = src - // Override attackby so we disallow trunkremoval when somethings ontop -/obj/structure/disposalpipe/trunk/attackby__legacy__attackchain(obj/item/I, mob/user, params) - +/// Disallow trunkremoval when something's on top +/obj/structure/disposalpipe/trunk/item_interaction(mob/living/user, obj/item/I, list/modifiers) //Disposal bins or chutes //Disposal constructors var/obj/structure/disposalconstruct/C = locate() in src.loc if(C && C.anchored) - return + return ITEM_INTERACT_COMPLETE var/turf/T = src.loc if(T.intact || T.transparent_floor) - return // prevent interaction with T-scanner revealed pipes + // prevent interaction with T-scanner revealed pipes + return ITEM_INTERACT_COMPLETE src.add_fingerprint(user) // would transfer to next pipe segment, but we are in a trunk diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index e6e61617921..101dceeab83 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -35,7 +35,8 @@ qdel(src) -/obj/structure/big_delivery/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params) +/obj/structure/big_delivery/item_interaction(mob/living/user, obj/item/W, list/modifiers) + . = ITEM_INTERACT_COMPLETE if(istype(W, /obj/item/dest_tagger)) var/obj/item/dest_tagger/O = W diff --git a/code/modules/ruins/lavalandruin_code/dead_ratvar.dm b/code/modules/ruins/lavalandruin_code/dead_ratvar.dm index c67bd5df0b6..8941dc36fe3 100644 --- a/code/modules/ruins/lavalandruin_code/dead_ratvar.dm +++ b/code/modules/ruins/lavalandruin_code/dead_ratvar.dm @@ -92,7 +92,8 @@ return default_unfasten_wrench(user, I, 10) -/obj/structure/clockwork/wall_gear/attackby__legacy__attackchain(obj/item/I, mob/user, params) +/obj/structure/clockwork/wall_gear/item_interaction(mob/living/user, obj/item/I, list/modifiers) + . = ITEM_INTERACT_COMPLETE if(istype(I, /obj/item/stack/tile/brass)) var/obj/item/stack/tile/brass/W = I if(W.get_amount() < 1) @@ -122,7 +123,7 @@ qdel(src) else to_chat(user, "You need more brass to make a [anchored ? "false ":""]wall!") - return 1 + return return ..() /obj/structure/clockwork/wall_gear/deconstruct(disassembled = TRUE) diff --git a/code/tests/_game_test_puppeteer.dm b/code/tests/_game_test_puppeteer.dm index 05db0cbd286..130a6938158 100644 --- a/code/tests/_game_test_puppeteer.dm +++ b/code/tests/_game_test_puppeteer.dm @@ -48,6 +48,11 @@ origin_test.Fail("could not spawn obj [obj_type] near [src]") +/datum/test_puppeteer/proc/spawn_fast_tool(item_type) + var/obj/item/fast_tool = spawn_obj_in_hand(item_type) + fast_tool.toolspeed = 0 + return fast_tool + /datum/test_puppeteer/proc/use_item_in_hand() var/obj/item/item = puppet.get_active_hand() if(!item) @@ -176,3 +181,6 @@ puppet.ClickOn(puppet) puppet.next_click = world.time puppet.next_move = world.time + +/datum/test_puppeteer/proc/drop_held_item() + puppet.drop_item_to_ground(puppet.get_active_hand()) diff --git a/code/tests/attack_chain/test_attack_chain_structures.dm b/code/tests/attack_chain/test_attack_chain_structures.dm new file mode 100644 index 00000000000..0e41bfc85a3 --- /dev/null +++ b/code/tests/attack_chain/test_attack_chain_structures.dm @@ -0,0 +1,324 @@ +/datum/game_test/room_test/attack_chain_structures + testing_area_name = "test_attack_chain_structures.dmm" + var/list/structure_instances_by_type = list() + +/datum/game_test/room_test/attack_chain_structures/proc/teleport_to_first(datum/test_puppeteer/player, obj_type, dir=EAST) + if(length(structure_instances_by_type[obj_type])) + for(var/obj/object in structure_instances_by_type[obj_type]) + if(!QDELETED(object)) + player.puppet.forceMove(get_step(object, dir)) + return object + TEST_FAIL("could not find [obj_type] to teleport puppet to") + +/datum/game_test/room_test/attack_chain_structures/New() + . = ..() + for(var/turf/T in available_turfs) + for(var/obj/structure/structure in T) + LAZYOR(structure_instances_by_type[structure.type], structure) + +/datum/game_test/room_test/attack_chain_structures/Run() + var/datum/test_puppeteer/player = new(src) + player.puppet.name = "Player" + + player.puppet.mind.add_antag_datum(/datum/antagonist/cultist) + player.spawn_obj_in_hand(/obj/item/melee/cultblade/dagger) + + var/forge = teleport_to_first(player, /obj/structure/cult/functional/forge) + player.click_on(forge) + TEST_ASSERT_LAST_CHATLOG(player, "You unsecure [forge] from the floor") + player.drop_held_item() + + var/obj/structure/ai_core/core = teleport_to_first(player, /obj/structure/ai_core) + player.spawn_obj_in_hand(/obj/item/circuitboard/aicore) + player.click_on(core) + TEST_ASSERT_LAST_CHATLOG(player, "You place the circuit board inside the frame") + + var/shell = teleport_to_first(player, /obj/structure/constructshell) + var/obj/item/soulstone/soulstone = player.spawn_obj_in_hand(/obj/item/soulstone) + soulstone.purified = TRUE + player.click_on(shell) + TEST_ASSERT_LAST_CHATLOG(player, "An overwhelming feeling of dread comes over you") + player.drop_held_item() + player.rejuvenate() + + var/obj/structure/computerframe/frame = teleport_to_first(player, /obj/structure/computerframe) + var/obj/circuitboard = player.spawn_obj_in_hand(/obj/item/circuitboard/computer/sat_control) + player.click_on(frame) + TEST_ASSERT_LAST_CHATLOG(player, "You place [circuitboard] inside the computer frame") + + var/barricade = teleport_to_first(player, /obj/structure/barricade/wooden) + player.spawn_obj_in_hand(/obj/item/stack/sheet/wood) + player.click_on(barricade) + TEST_ASSERT_LAST_CHATLOG(player, "You need at least five wooden planks to make a wall") + player.drop_held_item() + + var/firelock_frame = teleport_to_first(player, /obj/structure/firelock_frame) + var/obj/item/firelock_electronics/electronics = player.spawn_fast_tool(/obj/item/firelock_electronics) + player.click_on(firelock_frame) + TEST_ASSERT_LAST_CHATLOG(player, "You insert and secure [electronics]") + + var/machine_frame = teleport_to_first(player, /obj/structure/machine_frame) + player.spawn_fast_tool(/obj/item/stack/cable_coil{amount = 5}) + player.click_on(machine_frame) + TEST_ASSERT_LAST_CHATLOG(player, "You add cables to the frame.") + + var/obj/structure/largecrate/large_crate = teleport_to_first(player, /obj/structure/largecrate) + large_crate.manifest = new /obj/item/paper/manifest(null) + player.spawn_obj_in_hand(/obj/item/paper) + player.click_on(large_crate) + TEST_ASSERT_LAST_CHATLOG(player, "You tear the manifest off of the crate") + player.drop_held_item() + + var/obj/structure/displaycase/displaycase = teleport_to_first(player, /obj/structure/displaycase) + var/obj/id_card = player.spawn_obj_in_hand(/obj/item/card/id/assistant) + player.click_on(displaycase) + TEST_ASSERT_LAST_CHATLOG(player, "You use [id_card] to open [displaycase]") + player.put_away(id_card) + var/obj/item/toy/crayon/crayon = player.spawn_obj_in_hand(/obj/item/toy/crayon) + player.click_on(displaycase) + TEST_ASSERT_LAST_CHATLOG(player, "You put [crayon] on display") + player.retrieve(id_card) + player.click_on(displaycase) + TEST_ASSERT_LAST_CHATLOG(player, "You use [id_card] to close [displaycase]") + player.put_away(id_card) + var/obj/baton = player.spawn_obj_in_hand(/obj/item/melee/baton/loaded) + player.set_intent(INTENT_HARM) + player.click_on(displaycase) + TEST_ASSERT_LAST_CHATLOG(player, "You hit [displaycase] with [baton]") + qdel(baton) + + var/obj/assembly = teleport_to_first(player, /obj/structure/door_assembly) + player.spawn_fast_tool(/obj/item/wrench) + player.click_on(assembly) + TEST_ASSERT_LAST_CHATLOG(player, "You secure [assembly].") + player.drop_held_item() + player.spawn_fast_tool(/obj/item/stack/cable_coil) + player.click_on(assembly) + TEST_ASSERT_LAST_CHATLOG(player, "You wire the airlock assembly.") + player.drop_held_item() + + var/obj/girder = teleport_to_first(player, /obj/structure/girder/cult) + player.puppet.mind.add_antag_datum(/datum/antagonist/cultist) + player.spawn_obj_in_hand(/obj/item/melee/cultblade/dagger) + player.click_on(girder) + TEST_ASSERT_LAST_CHATLOG(player, "You demolish [girder].") + player.drop_held_item() + + girder = teleport_to_first(player, /obj/structure/girder) + player.spawn_fast_tool(/obj/item/stack/sheet/metal{amount = 2}) + player.click_on(girder) + TEST_ASSERT_LAST_CHATLOG(player, "You add the plating.") + + girder = teleport_to_first(player, /obj/structure/girder) + player.spawn_fast_tool(/obj/item/gun/energy/plasmacutter) + player.click_on(girder) + TEST_ASSERT_LAST_CHATLOG(player, "You slice apart the girder.") + player.drop_held_item() + + var/obj/structure/guillotine/guillotine = teleport_to_first(player, /obj/structure/guillotine) + guillotine.blade_sharpness -= 1 + player.spawn_fast_tool(/obj/item/whetstone) + player.click_on(guillotine) + TEST_ASSERT_LAST_CHATLOG(player, "You sharpen the large blade of [guillotine]") + player.drop_held_item() + + var/obj/weldingtool = player.spawn_fast_tool(/obj/item/weldingtool) + player.use_item_in_hand() + player.set_intent(INTENT_HARM) + player.click_on(guillotine) + TEST_ASSERT_LAST_CHATLOG(player, "You slice clean through the guillotine!") + player.put_away(weldingtool) + player.set_intent(INTENT_HELP) + + var/obj/structure/table_frame/table_frame = teleport_to_first(player, /obj/structure/table_frame) + table_frame.construction_time = 0 + player.spawn_obj_in_hand(/obj/item/stack/sheet/metal) + player.click_on(table_frame) + TEST_ASSERT_LAST_CHATLOG(player, "You start adding the metal to [table_frame]") + player.spawn_fast_tool(/obj/item/wrench) + var/table = player.find_nearby(/obj/structure/table) + player.click_on(table) + TEST_ASSERT_LAST_CHATLOG(player, "You dismantle [table]") + player.drop_held_item() + + var/obj/inflatable = teleport_to_first(player, /obj/structure/inflatable) + player.spawn_obj_in_hand(/obj/item/kitchen/knife) + player.click_on(inflatable) + TEST_ASSERT_LAST_CHATLOG(player, "[inflatable] rapidly deflates!") + player.drop_held_item() + + var/obj/kitchenspike_frame = teleport_to_first(player, /obj/structure/kitchenspike_frame) + player.spawn_obj_in_hand(/obj/item/stack/rods/ten) + player.click_on(kitchenspike_frame) + TEST_ASSERT_LAST_CHATLOG(player, "You add spikes to the frame.") + player.drop_held_item() + + var/obj/structure/kitchenspike/spike = teleport_to_first(player, /obj/structure/kitchenspike) + spike.impale_time = 0 + var/mob/living/pig = player.spawn_mob_nearby(/mob/living/basic/pig) + pig.grabbedby(player.puppet) + player.click_on(spike) + TEST_ASSERT_LAST_CHATLOG(player, "[player.puppet] slams [pig] onto the meat spike!") + + var/obj/structure/lattice/lattice = teleport_to_first(player, /obj/structure/lattice) + var/turf/space_turf = get_turf(lattice) + player.spawn_fast_tool(/obj/item/wirecutters) + player.click_on(lattice) + TEST_ASSERT_LAST_CHATLOG(player, "Slicing [lattice.name] joints...") + player.drop_held_item() + player.spawn_fast_tool(/obj/item/stack/rods/fifty) + player.click_on(space_turf) + TEST_ASSERT_LAST_CHATLOG(player, "Constructing support lattice...") + TEST_ASSERT_NOTNULL(locate(/obj/structure/lattice) in space_turf, "Could not find constructed lattice") + player.drop_held_item() + + var/obj/structure/loom/loom = teleport_to_first(player, /obj/structure/loom) + loom.disassemble_speed = 0 + var/obj/item/stack/sheet/cotton/cotton = player.spawn_obj_in_hand(/obj/item/stack/sheet/cotton) + cotton.amount = 4 + cotton.pull_effort = 0 + player.click_on(loom) + TEST_ASSERT_LAST_CHATLOG(player, "You weave [cotton] into a workable fabric.") + player.spawn_fast_tool(/obj/item/crowbar) + player.click_on(loom) + TEST_ASSERT_LAST_CHATLOG(player, "You dismantle [loom]") + player.drop_held_item() + + var/obj/structure/mineral_door/iron/door = teleport_to_first(player, /obj/structure/mineral_door/iron) + player.spawn_fast_tool(/obj/item/pickaxe) + player.click_on(door) + TEST_ASSERT_LAST_CHATLOG(player, "You finished digging.") + player.drop_held_item() + + var/obj/mirror = teleport_to_first(player, /obj/structure/mirror/magic) + var/starting_integrity = mirror.obj_integrity + player.spawn_fast_tool(/obj/item/weldingtool) + player.set_intent(INTENT_HARM) + player.click_on(mirror) + TEST_ASSERT_EQUAL(mirror.obj_integrity, starting_integrity, "magic mirror took damage") + player.drop_held_item() + player.set_intent(INTENT_HELP) + + var/obj/noticeboard = teleport_to_first(player, /obj/structure/noticeboard) + player.spawn_obj_in_hand(/obj/item/paper) + player.click_on(noticeboard) + TEST_ASSERT_LAST_CHATLOG(player, "You pin the paper to the noticeboard.") + + var/obj/structure/reflector/reflector = teleport_to_first(player, /obj/structure/reflector) + var/turf/T = get_turf(reflector) + player.spawn_fast_tool(/obj/item/stack/sheet/glass/fifty) + player.click_on(reflector) + // no chat messages for this construction apparently + TEST_ASSERT_NOTNULL(locate(/obj/structure/reflector/single) in T, "could not find constructed reflector") + player.drop_held_item() + + var/obj/structure/safe/safe = teleport_to_first(player, /obj/structure/safe) + safe.open = TRUE + var/obj/disk = player.spawn_obj_in_hand(/obj/item/disk/design_disk) + player.click_on(safe) + TEST_ASSERT_LAST_CHATLOG(player, "You put [disk] in [safe].") + safe.open = FALSE + var/obj/gun = player.spawn_obj_in_hand(/obj/item/gun/energy/laser) + player.click_on(safe) + TEST_ASSERT_LAST_CHATLOG(player, "You can't put [gun] into the safe while it is closed!") + player.drop_held_item() + + var/obj/structure/shelf/shelf = teleport_to_first(player, /obj/structure/shelf) + var/obj/box = player.spawn_obj_in_hand(/obj/item/storage/box/beakers) + player.click_on(shelf, "icon-x=8;icon-y=10") + TEST_ASSERT_LAST_CHATLOG(player, "You place [box] on [shelf].") + var/obj/wrench = player.spawn_fast_tool(/obj/item/wrench) + player.click_on(shelf, "icon-x=24;icon-y=10") + TEST_ASSERT_LAST_CHATLOG(player, "You place [wrench] on [shelf].") + player.spawn_fast_tool(/obj/item/wrench) + player.set_intent(INTENT_HARM) + player.click_on(shelf) + TEST_ASSERT_LAST_CHATLOG(player, "You disassemble [shelf].") + player.drop_held_item() + + var/obj/structure/statue/hop_statue = teleport_to_first(player, /obj/structure/statue/gold/hop) + player.spawn_fast_tool(/obj/item/gun/energy/plasmacutter) + player.click_on(hop_statue) + TEST_ASSERT_LAST_CHATLOG(player, "You slice apart [hop_statue].") + player.drop_held_item() + + var/obj/structure/snowman/built/snowman = teleport_to_first(player, /obj/structure/snowman/built) + var/old_integrity = snowman.obj_integrity + player.spawn_fast_tool(/obj/item/weldingtool) + player.set_intent(INTENT_HARM) + player.click_on(snowman) + TEST_ASSERT_NOTEQUAL(snowman.obj_integrity, old_integrity, "snowman didn't take damage") + player.drop_held_item() + player.spawn_obj_in_hand(/obj/item/snowball) + player.set_intent(INTENT_HELP) + player.click_on(snowman) + TEST_ASSERT_LAST_CHATLOG(player, "You patch some of the damage on [snowman]") + + var/obj/structure/bed/roller/roller_bed = teleport_to_first(player, /obj/structure/bed/roller) + player.spawn_obj_in_hand(/obj/item/roller_holder) + player.click_on(roller_bed) + TEST_ASSERT_LAST_CHATLOG(player, "You collapse \the [roller_bed].") + player.drop_held_item() + + var/obj/structure/big_delivery/delivery = teleport_to_first(player, /obj/structure/big_delivery) + var/obj/item/dest_tagger/tagger = player.spawn_obj_in_hand(/obj/item/dest_tagger) + tagger.currTag = 2 + player.click_on(delivery) + TEST_ASSERT_LAST_CHATLOG(player, "*CARGO BAY*") + player.drop_held_item() + + var/obj/structure/windoor_assembly/windoor_assembly = teleport_to_first(player, /obj/structure/windoor_assembly) + player.spawn_fast_tool(/obj/item/wrench) + player.click_on(windoor_assembly) + TEST_ASSERT_LAST_CHATLOG(player, "You secure the windoor assembly.") + player.drop_held_item() + player.spawn_fast_tool(/obj/item/stack/cable_coil) + player.click_on(windoor_assembly) + TEST_ASSERT_LAST_CHATLOG(player, "You wire the windoor.") + player.drop_held_item() + + var/obj/crate = teleport_to_first(player, /obj/structure/closet/crate/secure/loot) + player.spawn_fast_tool(/obj/item/multitool) + player.click_on(crate) + TEST_ASSERT_LAST_CHATLOG(player, "Anti-Tamper Bomb will activate after 10 failed access attempts") + player.drop_held_item() + + var/obj/structure/flora/ash/ashflora = teleport_to_first(player, /obj/structure/flora/ash) + ashflora.harvest_time = 0 + ashflora.harvest_amount_high = 1 // so we always get the same chat message + player.spawn_fast_tool(/obj/item/kitchen/knife) + player.click_on(ashflora) + TEST_ASSERT_LAST_CHATLOG(player, "You pick a mushroom, but fail to collect many shavings from its cap.") + player.drop_held_item() + + var/obj/orebox = teleport_to_first(player, /obj/structure/ore_box) + var/obj/item/storage/ore_bag = player.spawn_fast_tool(/obj/item/storage/bag/ore) + var/obj/item/stack/ore/iron/iron_ore = new(player.puppet.loc) + iron_ore.amount = 10 + ore_bag.handle_item_insertion(iron_ore) + player.click_on(orebox) + TEST_ASSERT_LAST_CHATLOG(player, "You empty the satchel into the box.") + player.drop_held_item() + + var/obj/filing_cabinet = teleport_to_first(player, /obj/structure/filingcabinet) + var/obj/paper = player.spawn_fast_tool(/obj/item/paper) + player.click_on(filing_cabinet) + TEST_ASSERT_LAST_CHATLOG(player, "You put [paper.name] in [filing_cabinet].") + + var/obj/cable = teleport_to_first(player, /obj/structure/cable, dir = EAST) + player.spawn_fast_tool(/obj/item/stack/cable_coil/ten) + T = get_turf(cable) + TEST_ASSERT_EQUAL(length(T.contents), 1, "couldn't find one cable on tile") + player.click_on(get_turf(cable)) + TEST_ASSERT_EQUAL(length(T.contents), 2, "didn't add cable to tile") + player.drop_held_item() + + var/obj/structure/fermenting_barrel/barrel = teleport_to_first(player, /obj/structure/fermenting_barrel) + var/obj/item/reagent_containers/glass/bucket/bucket = player.spawn_obj_in_hand(/obj/item/reagent_containers/glass/bucket) + barrel.reagents.add_reagent("beer", 300) + player.click_on(barrel) + TEST_ASSERT_LAST_CHATLOG(player, "You fill [bucket] with 20 units of the contents of [barrel]") + + var/obj/water_cooler = teleport_to_first(player, /obj/structure/reagent_dispensers/water_cooler) + player.click_on(water_cooler) + TEST_ASSERT_LAST_CHATLOG(player, "You fill [bucket] with 20 units of the contents of [water_cooler]") diff --git a/code/tests/game_tests.dm b/code/tests/game_tests.dm index 68b7879a366..464fa77b413 100644 --- a/code/tests/game_tests.dm +++ b/code/tests/game_tests.dm @@ -13,6 +13,8 @@ #include "attack_chain\test_attack_chain_borgs.dm" #include "attack_chain\test_attack_chain_cult_dagger.dm" #include "attack_chain\test_attack_chain_machinery.dm" +#include "attack_chain\test_attack_chain_structures.dm" +#include "attack_chain\test_attack_chain_stunbaton.dm" #include "attack_chain\test_attack_chain_mobs.dm" #include "attack_chain\test_attack_chain_reagent_containers.dm" #include "attack_chain\test_attack_chain_stunbaton.dm" diff --git a/tools/ci/check_legacy_attack_chain.py b/tools/ci/check_legacy_attack_chain.py index be18a0a502e..b6d6818725c 100644 --- a/tools/ci/check_legacy_attack_chain.py +++ b/tools/ci/check_legacy_attack_chain.py @@ -37,10 +37,10 @@ class AttackChainCall: def make_error_from_procdecl(proc_decl: ProcDecl, msg) -> str: if os.getenv("GITHUB_ACTIONS") == "true": - return f"::error file={proc_decl.source_info.file_path},line={proc_decl.source_info.line},title=Attack Chain::{proc_decl.source_info.file_path}:{proc_decl.source_info.line}: {RED}{msg}{NC}" + return f"::error file={proc_decl.source_loc.file_path},line={proc_decl.source_loc.line},title=Attack Chain::{proc_decl.source_loc.file_path}:{proc_decl.source_loc.line}: {RED}{msg}{NC}" else: - return f"{proc_decl.source_info.file_path}:{proc_decl.source_info.line}: {RED}{msg}{NC}" + return f"{proc_decl.source_loc.file_path}:{proc_decl.source_loc.line}: {RED}{msg}{NC}" # Walker for determining if a proc contains any calls to a legacy attack chain @@ -167,6 +167,9 @@ if __name__ == "__main__": dme = DME.from_file("paradise.dme", parse_procs=True) for pth in dme.subtypesof("/"): + if pth in IGNORED_TYPES: + continue + td = dme.types[pth] if any( [