From 06608081d28ca9480a61d631ae6f14419d017afc Mon Sep 17 00:00:00 2001 From: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:07:43 -0400 Subject: [PATCH] Moves a greater manyer morer things from attackby() to item_interaction() (#96739) ## About The Pull Request 50 files, plus additonal file that was necessary because I slightly refactored windoor construction. This ended up like three and a half times larger than most of the other ones, I really wasn't meaning for that to happen. Maybe its because I more vigorously enforced the empty line after every return thing. The only way to find out is to read 1700 lines of changes, and I don't feel like doing that again. I pinky promise it all works, and I've tested every item changed individually. Changes beyond conversion: You can't welder down reinforced falsewalls anymore, pretty sure it was an oversight because they're supposed to be taken down by wirecutters You can right click to close gun lockers with an empty hand, because otherwise you can't close the lockers at all if there's a gun in them Meatspikes no longer runtime on construction due to the old trick of balloon alert + qdel Windoor assembly no longer SUCKS DICK!!, it's no longer storing essentially a boolean in an undocumented number in a string, it no longer requires a VERB to flip its direction. on a related note, the creator of the windoor assembly construction steps has been sent to live on a farm far out in the country Also, a quick note about how these prs are gonna fuck everything up until they're all together. There's a lot more places where `attackby()` is directly called than I would have assumed, and given as those are being changed to call `item_interaction()` potentially(usually) in a different pr than the pr in which that atom's `attackby()` is actually converted, that function's not going to work at all until both are merged. The good news is that almost every instance this is happening, it's pure convenience, where the user would have access to both items anyway and could just manually call the attack chain by clicking them together. Instances where this is not the case are being skipped over until they can be packaged together to avoid the issue, but I'm not bothering to do this on ones where the desync won't make an interaction actually unusable, because that would require me to turn a 1700 line pr into a 3500 line pr and I really was aiming for like 500 ## Why It's Good For The Game Ignore the paragraph about how I expect this to create a hostage situation where the only fix to the bugs I make is to merge my other prs, and instead think about how cool swing combat would be and how much you want it ## Changelog :cl: fix: you now can only use a wirecutter to take down a reinforced falsewall fix: meatspikes no longer runtime on construction fix: you no longer have to use a verb that you can't use to flip windoor assemblies qol: you can right click a gun locker to close it code: 50 files have been moved from attackby() to item_interaction() /:cl: --- code/game/machinery/doors/windowdoor.dm | 16 +- code/game/objects/items/tanks/watertank.dm | 11 +- code/game/objects/items/tcg/tcg.dm | 38 +- code/game/objects/items/tcg/tcg_machines.dm | 43 +- .../engineering/painter/airlock_painter.dm | 27 +- .../items/tools/engineering/weldingtool.dm | 10 +- code/game/objects/items/tools/theft_tools.dm | 57 ++- .../objects/items/weaponry/melee/baton.dm | 57 +-- .../objects/items/weaponry/melee/dualsaber.dm | 21 +- .../game/objects/items/weaponry/melee/misc.dm | 31 +- .../objects/items/weaponry/melee/powerfist.dm | 21 +- .../items/weaponry/ranged/pneumatic_cannon.dm | 41 +- code/game/objects/items/weaponry/shields.dm | 84 ++-- .../objects/structures/beds_chairs/bed.dm | 64 +-- code/game/objects/structures/bonfire.dm | 48 +- .../game/objects/structures/cannons/cannon.dm | 62 +-- code/game/objects/structures/curtains.dm | 10 +- .../game/objects/structures/detectiveboard.dm | 52 +- code/game/objects/structures/displaycase.dm | 196 +++++--- code/game/objects/structures/door_assembly.dm | 356 ++++++++------ code/game/objects/structures/dresser.dm | 16 +- code/game/objects/structures/electricchair.dm | 14 +- code/game/objects/structures/false_walls.dm | 28 +- code/game/objects/structures/fence.dm | 55 +-- code/game/objects/structures/fireaxe.dm | 91 ++-- code/game/objects/structures/flora.dm | 45 +- code/game/objects/structures/fluff.dm | 24 +- code/game/objects/structures/grille.dm | 118 ++--- code/game/objects/structures/guillotine.dm | 80 ++-- code/game/objects/structures/guncase.dm | 36 +- code/game/objects/structures/janitor.dm | 122 ++--- code/game/objects/structures/kitchen_spike.dm | 27 +- code/game/objects/structures/ladders.dm | 15 +- code/game/objects/structures/maintenance.dm | 44 +- code/game/objects/structures/mineral_doors.dm | 44 +- code/game/objects/structures/morgue.dm | 12 +- code/game/objects/structures/noticeboard.dm | 35 +- .../game/objects/structures/ore_containers.dm | 10 +- code/game/objects/structures/railings.dm | 38 +- code/game/objects/structures/reflector.dm | 60 ++- code/game/objects/structures/safe.dm | 39 +- code/game/objects/structures/shower.dm | 38 +- code/game/objects/structures/spawner.dm | 10 +- code/game/objects/structures/stairs.dm | 39 +- .../game/objects/structures/tank_dispenser.dm | 40 +- code/game/objects/structures/tank_holder.dm | 30 +- code/game/objects/structures/toiletbong.dm | 5 - .../objects/structures/training_machine.dm | 16 +- code/game/objects/structures/votingbox.dm | 26 +- .../objects/structures/windoor_assembly.dm | 449 ++++++++++-------- code/game/objects/structures/window.dm | 179 ++++--- 51 files changed, 1697 insertions(+), 1333 deletions(-) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 01ec6e7b66c..02c09f28516 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -393,24 +393,24 @@ . = ..() if(density || operating) to_chat(user, span_warning("You need to open the door to access the maintenance panel!")) - return + return ITEM_INTERACT_BLOCKING add_fingerprint(user) tool.play_tool_sound(src) toggle_panel_open() to_chat(user, span_notice("You [panel_open ? "open" : "close"] the maintenance panel.")) - return TRUE + return ITEM_INTERACT_SUCCESS /obj/machinery/door/window/crowbar_act(mob/living/user, obj/item/tool) . = ..() if(!panel_open || density || operating) - return + return ITEM_INTERACT_BLOCKING add_fingerprint(user) user.visible_message(span_notice("[user] removes the electronics from \the [src]."), \ span_notice("You start to remove electronics from \the [src]...")) if(!tool.use_tool(src, user, 40, volume=50)) - return + return ITEM_INTERACT_BLOCKING if(!panel_open || density || operating || !loc) - return + return ITEM_INTERACT_BLOCKING var/obj/structure/windoor_assembly/windoor_assembly = new /obj/structure/windoor_assembly(loc) switch(base_state) if("left") @@ -424,14 +424,14 @@ windoor_assembly.facing = "r" windoor_assembly.secure = TRUE windoor_assembly.set_anchored(TRUE) - windoor_assembly.state= "02" + windoor_assembly.cables_added = TRUE windoor_assembly.setDir(dir) windoor_assembly.update_appearance() windoor_assembly.created_name = name if(obj_flags & EMAGGED) to_chat(user, span_warning("You discard the damaged electronics.")) qdel(src) - return + return ITEM_INTERACT_SUCCESS to_chat(user, span_notice("You remove the airlock electronics.")) var/obj/item/electronics/airlock/dropped_electronics if(!electronics) @@ -446,7 +446,7 @@ electronics = null dropped_electronics.forceMove(drop_location()) qdel(src) - return TRUE + return ITEM_INTERACT_SUCCESS /obj/machinery/door/window/interact(mob/user) //for sillycones try_to_activate_door(user) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 89970927cd5..a08a5faf3eb 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -89,12 +89,11 @@ GAME_VERB(/obj/item/watertank, toggle_mister_verb, "Toggle Mister", null) else return ..() -/obj/item/watertank/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - if(attacking_item == noz) - remove_noz() - return TRUE - else - return ..() +/obj/item/watertank/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(tool != noz) + return NONE + remove_noz() + return ITEM_INTERACT_SUCCESS /obj/item/watertank/dropped(mob/user) ..() diff --git a/code/game/objects/items/tcg/tcg.dm b/code/game/objects/items/tcg/tcg.dm index 0f22083f67b..ee74c9daa27 100644 --- a/code/game/objects/items/tcg/tcg.dm +++ b/code/game/objects/items/tcg/tcg.dm @@ -128,25 +128,29 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) icon_state = template.icon_state return ..() -/obj/item/tcgcard/attackby(obj/item/item, mob/living/user, list/modifiers, list/attack_modifiers) - if(istype(item, /obj/item/tcgcard)) - var/obj/item/tcgcard/second_card = item +/obj/item/tcgcard/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/tcgcard)) + var/obj/item/tcgcard/second_card = tool var/obj/item/tcgcard_deck/new_deck = new /obj/item/tcgcard_deck(drop_location()) new_deck.flipped = flipped user.transferItemToLoc(second_card, new_deck)//Start a new pile with both cards, in the order of card placement. user.transferItemToLoc(src, new_deck) new_deck.update_icon_state() user.put_in_hands(new_deck) - if(istype(item, /obj/item/tcgcard_deck)) - var/obj/item/tcgcard_deck/old_deck = item + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/tcgcard_deck)) + var/obj/item/tcgcard_deck/old_deck = tool if(length(old_deck.contents) >= 30) to_chat(user, span_notice("This pile has too many cards for a regular deck!")) - return + return ITEM_INTERACT_BLOCKING user.transferItemToLoc(src, old_deck) flipped = old_deck.flipped old_deck.update_appearance() update_appearance() - return ..() + return ITEM_INTERACT_SUCCESS + + return NONE /obj/item/tcgcard/proc/check_menu(mob/living/user) if(!istype(user)) @@ -254,16 +258,16 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) return FALSE return TRUE -/obj/item/tcgcard_deck/attackby(obj/item/item, mob/living/user, list/modifiers, list/attack_modifiers) - . = ..() - if(istype(item, /obj/item/tcgcard)) - if(contents.len >= 30) - to_chat(user, span_notice("This pile has too many cards for a regular deck!")) - return FALSE - var/obj/item/tcgcard/new_card = item - new_card.flipped = flipped - new_card.forceMove(src) - +/obj/item/tcgcard_deck/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/tcgcard)) + return NONE + if(contents.len >= 30) + to_chat(user, span_notice("This pile has too many cards for a regular deck!")) + return ITEM_INTERACT_BLOCKING + var/obj/item/tcgcard/new_card = tool + new_card.flipped = flipped + new_card.forceMove(src) + return ITEM_INTERACT_SUCCESS /obj/item/tcgcard_deck/attack_self(mob/living/carbon/user) shuffle_deck(user) diff --git a/code/game/objects/items/tcg/tcg_machines.dm b/code/game/objects/items/tcg/tcg_machines.dm index d1a562ac05b..f188747b9d3 100644 --- a/code/game/objects/items/tcg/tcg_machines.dm +++ b/code/game/objects/items/tcg/tcg_machines.dm @@ -24,27 +24,28 @@ var/summon_offset_x = 0 var/summon_offset_y = 1 -/obj/machinery/trading_card_holder/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/tcgcard) && current_summon == null) - current_card = I - card_template = current_card.extract_datum() - if(card_template.cardtype == "Creature") - if(!user.transferItemToLoc(current_card, src)) - return - to_chat(user, span_notice("You put the [current_card] card in [src].")) - icon_state = "card_holder_active" - update_appearance() - current_summon = new(locate(x + summon_offset_x, y + summon_offset_y, z)) - current_summon.template = card_template - current_summon.card_ref = current_card - current_summon.team_color = team_color - current_summon.load_model() - else - to_chat(user, span_notice("The [src] smartly rejects the non-creature card.")) - current_card = null - return ..() - else - return ..() +/obj/machinery/trading_card_holder/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/tcgcard) || current_summon) + return NONE + current_card = tool + card_template = current_card.extract_datum() + if(card_template.cardtype != "Creature") + to_chat(user, span_notice("The [src] smartly rejects the non-creature card.")) + current_card = null + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(current_card, src)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You put the [current_card] card in [src].")) + icon_state = "card_holder_active" + update_appearance() + current_summon = new(locate(x + summon_offset_x, y + summon_offset_y, z)) + current_summon.template = card_template + current_summon.card_ref = current_card + current_summon.team_color = team_color + current_summon.load_model() + return ITEM_INTERACT_SUCCESS GLOBAL_LIST_EMPTY(tcgcard_machine_radial_choices) diff --git a/code/game/objects/items/tools/engineering/painter/airlock_painter.dm b/code/game/objects/items/tools/engineering/painter/airlock_painter.dm index 246ab170465..87541da5108 100644 --- a/code/game/objects/items/tools/engineering/painter/airlock_painter.dm +++ b/code/game/objects/items/tools/engineering/painter/airlock_painter.dm @@ -131,18 +131,21 @@ ink_level = "dangerously high" . += span_notice("Its ink levels look [ink_level].") -/obj/item/airlock_painter/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) - if(istype(W, /obj/item/toner)) - if(ink) - to_chat(user, span_warning("[src] already contains \a [ink]!")) - return - if(!user.transferItemToLoc(W, src)) - return - to_chat(user, span_notice("You install [W] into [src].")) - ink = W - playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) - else - return ..() +/obj/item/airlock_painter/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/toner)) + return NONE + + if(ink) + to_chat(user, span_warning("[src] already contains \a [ink]!")) + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You install [tool] into [src].")) + ink = tool + playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) + return ITEM_INTERACT_SUCCESS /obj/item/airlock_painter/click_alt(mob/user) if(!ink) diff --git a/code/game/objects/items/tools/engineering/weldingtool.dm b/code/game/objects/items/tools/engineering/weldingtool.dm index afb4ae2b225..59520721f4e 100644 --- a/code/game/objects/items/tools/engineering/weldingtool.dm +++ b/code/game/objects/items/tools/engineering/weldingtool.dm @@ -122,12 +122,12 @@ flamethrower_screwdriver(tool, user) return ITEM_INTERACT_SUCCESS -/obj/item/weldingtool/attackby(obj/item/tool, mob/user, list/modifiers, list/attack_modifiers) - if(istype(tool, /obj/item/stack/rods)) - flamethrower_rods(tool, user) - else - . = ..() +/obj/item/weldingtool/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/stack/rods)) + return NONE + flamethrower_rods(tool, user) update_appearance() + return ITEM_INTERACT_SUCCESS /obj/item/weldingtool/cyborg_unequip(mob/user) if(!isOn()) diff --git a/code/game/objects/items/tools/theft_tools.dm b/code/game/objects/items/tools/theft_tools.dm index fae7befdff1..52b96d3b103 100644 --- a/code/game/objects/items/tools/theft_tools.dm +++ b/code/game/objects/items/tools/theft_tools.dm @@ -23,11 +23,11 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/item/nuke_core/attackby(obj/item/nuke_core_container/container, mob/user) - if(istype(container)) - container.load(src, user) - else - return ..() +/obj/item/nuke_core/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/nuke_core_container)) + return NONE + astype(tool, /obj/item/nuke_core_container).load(src, user) + return ITEM_INTERACT_SUCCESS /obj/item/nuke_core/process() if(cooldown < world.time - 60) @@ -72,15 +72,17 @@ if(ismob(loc)) to_chat(loc, span_warning("[src] is sealed, [core]'s radiation is contained.")) -/obj/item/nuke_core_container/attackby(obj/item/nuke_core/core, mob/user) - if(istype(core)) - if(!user.temporarilyRemoveItemFromInventory(core)) - to_chat(user, span_warning("The [core] is stuck to your hand!")) - return - else - load(core, user) - else - return ..() +/obj/item/nuke_core_container/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/nuke_core)) + return NONE + + if(!user.temporarilyRemoveItemFromInventory(tool)) + to_chat(user, span_warning("The [tool] is stuck to your hand!")) + return ITEM_INTERACT_BLOCKING + + load(tool, user) + return ITEM_INTERACT_SUCCESS + //snowflake screwdriver, works as a key to start nuke theft, traitor only /obj/item/screwdriver/nuke @@ -177,24 +179,27 @@ /obj/item/nuke_core/supermatter_sliver/can_be_pulled(user, force) // no drag memes return FALSE -/obj/item/nuke_core/supermatter_sliver/attackby(obj/item/W, mob/living/user, list/modifiers, list/attack_modifiers) - if(istype(W, /obj/item/hemostat/supermatter)) - var/obj/item/hemostat/supermatter/tongs = W +/obj/item/nuke_core/supermatter_sliver/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/hemostat/supermatter)) + var/obj/item/hemostat/supermatter/tongs = tool if (tongs.sliver) to_chat(user, span_warning("\The [tongs] is already holding a supermatter sliver!")) - return FALSE + return ITEM_INTERACT_BLOCKING forceMove(tongs) tongs.sliver = src tongs.update_appearance() to_chat(user, span_notice("You carefully pick up [src] with [tongs].")) - else if(istype(W, /obj/item/scalpel/supermatter) || istype(W, /obj/item/nuke_core_container/supermatter/)) // we don't want it to dust - return - else - to_chat(user, span_notice("As it touches \the [src], both \the [src] and \the [W] burst into dust!")) - radiation_pulse(user, max_range = 2, threshold = RAD_EXTREME_INSULATION, chance = 40) - playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) - qdel(W) - qdel(src) + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/scalpel/supermatter) || istype(tool, /obj/item/nuke_core_container/supermatter/)) // we don't want it to dust + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("As it touches \the [src], both \the [src] and \the [tool] burst into dust!")) + radiation_pulse(user, max_range = 2, threshold = RAD_EXTREME_INSULATION, chance = 40) + playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE) + qdel(tool) + qdel(src) + return ITEM_INTERACT_SUCCESS /obj/item/nuke_core/supermatter_sliver/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!isliving(hit_atom)) diff --git a/code/game/objects/items/weaponry/melee/baton.dm b/code/game/objects/items/weaponry/melee/baton.dm index a4ceccaa4eb..5769503f6bc 100644 --- a/code/game/objects/items/weaponry/melee/baton.dm +++ b/code/game/objects/items/weaponry/melee/baton.dm @@ -596,22 +596,24 @@ tool.play_tool_sound(src) return TRUE -/obj/item/melee/baton/security/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(item, /obj/item/stock_parts/power_store/cell)) - var/obj/item/stock_parts/power_store/cell/active_cell = item - if(cell) - to_chat(user, span_warning("[src] already has a cell!")) - else - if(active_cell.maxcharge < cell_hit_cost) - to_chat(user, span_notice("[src] requires a higher capacity cell.")) - return - if(!user.transferItemToLoc(item, src)) - return - cell = item - to_chat(user, span_notice("You install a cell in [src].")) - update_appearance() - else - return ..() +/obj/item/melee/baton/security/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/stock_parts/power_store/cell)) + return NONE + if(cell) + to_chat(user, span_warning("[src] already has a cell!")) + return ITEM_INTERACT_BLOCKING + + if(astype(tool, /obj/item/stock_parts/power_store/cell).maxcharge < cell_hit_cost) + to_chat(user, span_notice("[src] requires a higher capacity cell.")) + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + cell = tool + to_chat(user, span_notice("You install a cell in [src].")) + update_appearance() + return ITEM_INTERACT_SUCCESS /obj/item/melee/baton/security/proc/tryremovecell(mob/user) if(cell && can_remove_cell) @@ -837,37 +839,38 @@ /obj/item/melee/baton/security/cattleprod/add_deep_lore() return -/obj/item/melee/baton/security/cattleprod/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)//handles sticking a crystal onto a stunprod to make an improved cattleprod - if(!istype(item, /obj/item/stack)) +/obj/item/melee/baton/security/cattleprod/item_interaction(mob/living/user, obj/item/tool, list/modifiers)//handles sticking a crystal onto a stunprod to make an improved cattleprod + if(!istype(tool, /obj/item/stack)) return ..() if(!can_upgrade) user.visible_message(span_warning("This prod is already improved!")) - return ..() + return ITEM_INTERACT_BLOCKING if(cell) user.visible_message(span_warning("You can't put the crystal onto the stunprod while it has a power cell installed!")) - return ..() + return ITEM_INTERACT_BLOCKING var/our_prod - if(istype(item, /obj/item/stack/ore/bluespace_crystal)) - var/obj/item/stack/ore/bluespace_crystal/our_crystal = item + if(istype(tool, /obj/item/stack/ore/bluespace_crystal)) + var/obj/item/stack/ore/bluespace_crystal/our_crystal = tool our_crystal.use(1) our_prod = /obj/item/melee/baton/security/cattleprod/teleprod - else if(istype(item, /obj/item/stack/telecrystal)) - var/obj/item/stack/telecrystal/our_crystal = item + else if(istype(tool, /obj/item/stack/telecrystal)) + var/obj/item/stack/telecrystal/our_crystal = tool our_crystal.use(1) our_prod = /obj/item/melee/baton/security/cattleprod/telecrystalprod else - to_chat(user, span_notice("You don't think \the [item] will do anything to improve \the [src].")) - return ..() + to_chat(user, span_notice("You don't think \the [tool] will do anything to improve \the [src].")) + return ITEM_INTERACT_BLOCKING - to_chat(user, span_notice("You place \the [item] firmly into \the [sparkler].")) + to_chat(user, span_notice("You place \the [tool] firmly into \the [sparkler].")) remove_item_from_storage(user) qdel(src) var/obj/item/melee/baton/security/cattleprod/brand_new_prod = new our_prod(user.loc) user.put_in_hands(brand_new_prod) + return ITEM_INTERACT_SUCCESS /obj/item/melee/baton/security/cattleprod/try_stun(mob/living/target, mob/living/user, harmbatonning) return ..() && sparkler.activate() diff --git a/code/game/objects/items/weaponry/melee/dualsaber.dm b/code/game/objects/items/weaponry/melee/dualsaber.dm index 4bc19e01ded..762cd43269c 100644 --- a/code/game/objects/items/weaponry/melee/dualsaber.dm +++ b/code/game/objects/items/weaponry/melee/dualsaber.dm @@ -212,14 +212,13 @@ /obj/item/dualsaber/purple possible_colors = list("purple") -/obj/item/dualsaber/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) - if(W.tool_behaviour == TOOL_MULTITOOL) - if(!hacked) - hacked = TRUE - to_chat(user, span_warning("2XRNBW_ENGAGE")) - saber_color = "rainbow" - update_appearance() - else - to_chat(user, span_warning("It's starting to look like a triple rainbow - no, nevermind.")) - else - return ..() +/obj/item/dualsaber/multitool_act(mob/living/user, obj/item/tool) + if(hacked) + to_chat(user, span_warning("It's starting to look like a triple rainbow - no, nevermind.")) + return ITEM_INTERACT_BLOCKING + hacked = TRUE + to_chat(user, span_warning("2XRNBW_ENGAGE")) + saber_color = "rainbow" + update_appearance() + return ITEM_INTERACT_SUCCESS + diff --git a/code/game/objects/items/weaponry/melee/misc.dm b/code/game/objects/items/weaponry/melee/misc.dm index e012437dcde..753881c27aa 100644 --- a/code/game/objects/items/weaponry/melee/misc.dm +++ b/code/game/objects/items/weaponry/melee/misc.dm @@ -156,20 +156,25 @@ playsound(src, 'sound/items/weapons/batonextend.ogg', 50, TRUE) return COMPONENT_NO_DEFAULT_MESSAGE -/obj/item/melee/roastingstick/attackby(atom/target, mob/user) - ..() - if (istype(target, /obj/item/food/sausage)) - if (!HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE)) - to_chat(user, span_warning("You must extend [src] to attach anything to it!")) - return - if (held_sausage) - to_chat(user, span_warning("[held_sausage] is already attached to [src]!")) - return - if (user.transferItemToLoc(target, src)) - held_sausage = target - else - to_chat(user, span_warning("[target] doesn't seem to want to get on [src]!")) +/obj/item/melee/roastingstick/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if (!istype(tool, /obj/item/food/sausage)) + return NONE + + if (!HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE)) + to_chat(user, span_warning("You must extend [src] to attach anything to it!")) + return ITEM_INTERACT_BLOCKING + + if (held_sausage) + to_chat(user, span_warning("[held_sausage] is already attached to [src]!")) + return ITEM_INTERACT_BLOCKING + + if (!user.transferItemToLoc(tool, src)) + to_chat(user, span_warning("[tool] doesn't seem to want to get on [src]!")) + return ITEM_INTERACT_BLOCKING + + held_sausage = tool update_appearance() + return ITEM_INTERACT_SKIP_TO_ATTACK /obj/item/melee/roastingstick/attack_hand(mob/user, list/modifiers) ..() diff --git a/code/game/objects/items/weaponry/melee/powerfist.dm b/code/game/objects/items/weaponry/melee/powerfist.dm index 172806476bd..853d9db0bdf 100644 --- a/code/game/objects/items/weaponry/melee/powerfist.dm +++ b/code/game/objects/items/weaponry/melee/powerfist.dm @@ -72,17 +72,20 @@ update_tank(tank, TANK_REMOVING, user) return TRUE -/obj/item/melee/powerfist/attackby(obj/item/item_to_insert, mob/user, list/modifiers, list/attack_modifiers) - if(!istype(item_to_insert, /obj/item/tank/internals)) - return ..() +/obj/item/melee/powerfist/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/tank/internals)) + return NONE + if(tank) to_chat(user, span_notice("A tank is already present, remove it with a screwdriver first.")) - return - var/obj/item/tank/internals/tank_to_insert = item_to_insert - if(tank_to_insert.volume <= 3) - to_chat(user, span_warning("\The [tank_to_insert] is too small for \the [src].")) - return - update_tank(item_to_insert, TANK_INSERTING, user) + return ITEM_INTERACT_BLOCKING + + if(astype(tool, /obj/item/tank/internals).volume <= 3) + to_chat(user, span_warning("\The [tool] is too small for \the [src].")) + return ITEM_INTERACT_BLOCKING + + update_tank(tool, TANK_INSERTING, user) + return ITEM_INTERACT_SUCCESS /obj/item/melee/powerfist/proc/update_tank(obj/item/tank/internals/the_tank, removing = TANK_INSERTING, mob/living/carbon/human/user) if(removing) diff --git a/code/game/objects/items/weaponry/ranged/pneumatic_cannon.dm b/code/game/objects/items/weaponry/ranged/pneumatic_cannon.dm index ce16248146d..49846e8ee71 100644 --- a/code/game/objects/items/weaponry/ranged/pneumatic_cannon.dm +++ b/code/game/objects/items/weaponry/ranged/pneumatic_cannon.dm @@ -132,25 +132,36 @@ balloon_alert(user, "output level set to [pressure_setting_to_text(pressure_setting)]") return TRUE -/obj/item/pneumatic_cannon/attackby(obj/item/W, mob/living/user, list/modifiers, list/attack_modifiers) +/obj/item/pneumatic_cannon/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(user.combat_mode) - return ..() - if(istype(W, /obj/item/tank/internals)) + return NONE + if(!isitem(tool)) + return NONE + + if(istype(tool, /obj/item/tank/internals)) if(needs_air == FALSE) - return - if(!tank) - var/obj/item/tank/internals/IT = W - if(IT.volume <= 3) - to_chat(user, span_warning("\The [IT] is too small for \the [src].")) - return - updateTank(W, 0, user) - else if(W.type == type) + return ITEM_INTERACT_BLOCKING + + if(tank) + return ITEM_INTERACT_BLOCKING + + if(astype(tool, /obj/item/tank/internals).volume <= 3) + to_chat(user, span_warning("\The [tool] is too small for \the [src].")) + return ITEM_INTERACT_BLOCKING + + updateTank(tool, FALSE, user) + return ITEM_INTERACT_SUCCESS + + if(tool.type == type) to_chat(user, span_warning("You're fairly certain that putting a pneumatic cannon inside another pneumatic cannon would cause a spacetime disruption.")) - else if(loadedWeightClass >= maxWeightClass) + return ITEM_INTERACT_BLOCKING + + if(loadedWeightClass >= maxWeightClass) to_chat(user, span_warning("\The [src] can't hold any more items!")) - else if(isitem(W)) - var/obj/item/IW = W - load_item(IW, user) + return ITEM_INTERACT_BLOCKING + + load_item(tool, user) + return ITEM_INTERACT_SUCCESS /obj/item/pneumatic_cannon/proc/can_load_item(obj/item/I, mob/user) if(!istype(I)) //Players can't load non items, this allows for admin varedit inserts. diff --git a/code/game/objects/items/weaponry/shields.dm b/code/game/objects/items/weaponry/shields.dm index c2bc88b8748..ff86f296f80 100644 --- a/code/game/objects/items/weaponry/shields.dm +++ b/code/game/objects/items/weaponry/shields.dm @@ -187,17 +187,19 @@ slapcraft_recipes = slapcraft_recipe_list,\ ) -/obj/item/shield/riot/attackby(obj/item/attackby_item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(attackby_item, /obj/item/stack/sheet/mineral/titanium)) - if (atom_integrity >= max_integrity) - to_chat(user, span_warning("[src] is already in perfect condition.")) - return - var/obj/item/stack/sheet/mineral/titanium/titanium_sheet = attackby_item - titanium_sheet.use(1) - atom_integrity = max_integrity - to_chat(user, span_notice("You repair [src] with [titanium_sheet].")) - return - return ..() +/obj/item/shield/riot/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/stack/sheet/mineral/titanium)) + return NONE + + if (atom_integrity >= max_integrity) + to_chat(user, span_warning("[src] is already in perfect condition.")) + return ITEM_INTERACT_BLOCKING + + var/obj/item/stack/sheet/mineral/titanium/titanium_sheet = tool + titanium_sheet.use(1) + atom_integrity = max_integrity + to_chat(user, span_notice("You repair [src] with [titanium_sheet].")) + return ITEM_INTERACT_SUCCESS /obj/item/shield/riot/flash name = "strobe shield" @@ -263,22 +265,26 @@ owner?.update_held_items() addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_appearance)), 0.5 SECONDS, (TIMER_UNIQUE|TIMER_OVERRIDE)) //.5 second delay so the inhands sprite finishes its anim since inhands don't support flick(). -/obj/item/shield/riot/flash/attackby(obj/item/attackby_item, mob/user) - if(istype(attackby_item, /obj/item/assembly/flash/handheld)) - var/obj/item/assembly/flash/handheld/flash = attackby_item - if(flash.burnt_out) - to_chat(user, span_warning("No sense replacing it with a broken bulb!")) - return - else - to_chat(user, span_notice("You begin to replace the bulb...")) - if(do_after(user, 2 SECONDS, target = user)) - if(QDELETED(flash) || flash.burnt_out) - return - playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) - qdel(embedded_flash) - flash.forceMove(src) - return - return ..() +/obj/item/shield/riot/flash/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/assembly/flash/handheld)) + return ..() + + var/obj/item/assembly/flash/handheld/flash = tool + if(flash.burnt_out) + to_chat(user, span_warning("No sense replacing it with a broken bulb!")) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You begin to replace the bulb...")) + if(!do_after(user, 2 SECONDS, target = user)) + return ITEM_INTERACT_BLOCKING + + if(QDELETED(flash) || flash.burnt_out) + return ITEM_INTERACT_BLOCKING + + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) + qdel(embedded_flash) + flash.forceMove(src) + return ITEM_INTERACT_SUCCESS /obj/item/shield/riot/flash/emp_act(severity) . = ..() @@ -460,17 +466,19 @@ shield_break_leftover = /obj/item/stack/rods/ten armor_type = /datum/armor/item_shield/ballistic -/obj/item/shield/ballistic/attackby(obj/item/attackby_item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(attackby_item, /obj/item/stack/sheet/mineral/titanium)) - if (atom_integrity >= max_integrity) - to_chat(user, span_warning("[src] is already in perfect condition.")) - return - var/obj/item/stack/sheet/mineral/titanium/titanium_sheet = attackby_item - titanium_sheet.use(1) - atom_integrity = max_integrity - to_chat(user, span_notice("You repair [src] with [titanium_sheet].")) - return - return ..() +/obj/item/shield/ballistic/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/stack/sheet/mineral/titanium)) + return NONE + + if (atom_integrity >= max_integrity) + to_chat(user, span_warning("[src] is already in perfect condition.")) + return ITEM_INTERACT_BLOCKING + + var/obj/item/stack/sheet/mineral/titanium/titanium_sheet = tool + titanium_sheet.use(1) + atom_integrity = max_integrity + to_chat(user, span_notice("You repair [src] with [titanium_sheet].")) + return ITEM_INTERACT_SUCCESS /datum/armor/item_shield/improvised melee = 40 diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index b48169d6ecb..c5a7886e878 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -210,26 +210,28 @@ . += mutable_appearance(icon, "brakes_down") . += emissive_appearance(icon, "brakes_down", src, alpha = src.alpha) -/obj/structure/bed/medical/emergency/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(item, /obj/item/emergency_bed/silicon)) - var/obj/item/emergency_bed/silicon/silicon_bed = item - if(silicon_bed.loaded) - to_chat(user, span_warning("You already have a medical bed docked!")) - return +/obj/structure/bed/medical/emergency/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/emergency_bed/silicon)) + return NONE + var/obj/item/emergency_bed/silicon/silicon_bed = tool + if(silicon_bed.loaded) + to_chat(user, span_warning("You already have a medical bed docked!")) + return ITEM_INTERACT_BLOCKING - if(has_buckled_mobs()) - if(buckled_mobs.len > 1) - unbuckle_all_mobs() - user.visible_message(span_notice("[user] unbuckles all creatures from [src].")) - else - user_unbuckle_mob(buckled_mobs[1],user) - else - silicon_bed.loaded = src - forceMove(silicon_bed) - user.visible_message(span_notice("[user] collects [src]."), span_notice("You collect [src].")) - return TRUE - else - return ..() + if(has_buckled_mobs()) + if(buckled_mobs.len == 1) + user_unbuckle_mob(buckled_mobs[1],user) + return ITEM_INTERACT_SUCCESS + + unbuckle_all_mobs() + user.visible_message(span_notice("[user] unbuckles all creatures from [src].")) + return ITEM_INTERACT_SUCCESS + + + silicon_bed.loaded = src + forceMove(silicon_bed) + user.visible_message(span_notice("[user] collects [src]."), span_notice("You collect [src].")) + return ITEM_INTERACT_SUCCESS /obj/structure/bed/medical/emergency/attack_hand_secondary(mob/user, list/modifiers) . = ..() @@ -257,20 +259,20 @@ w_class = WEIGHT_CLASS_NORMAL // No more excuses, stop getting blood everywhere custom_materials = list(/datum/material/titanium = SHEET_MATERIAL_AMOUNT * 2.7, /datum/material/plastic = SHEET_MATERIAL_AMOUNT * 1.7) -/obj/item/emergency_bed/attackby(obj/item/item, mob/living/user, list/modifiers, list/attack_modifiers) - if(istype(item, /obj/item/emergency_bed/silicon)) - var/obj/item/emergency_bed/silicon/silicon_bed = item - if(silicon_bed.loaded) - to_chat(user, span_warning("[silicon_bed] already has a roller bed loaded!")) - return +/obj/item/emergency_bed/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/emergency_bed/silicon)) + return NONE - user.visible_message(span_notice("[user] loads [src]."), span_notice("You load [src] into [silicon_bed].")) - silicon_bed.loaded = new/obj/structure/bed/medical/emergency(silicon_bed) - qdel(src) //"Load" - return + var/obj/item/emergency_bed/silicon/silicon_bed = tool + if(silicon_bed.loaded) + to_chat(user, span_warning("[silicon_bed] already has a roller bed loaded!")) + return ITEM_INTERACT_BLOCKING + + user.visible_message(span_notice("[user] loads [src]."), span_notice("You load [src] into [silicon_bed].")) + silicon_bed.loaded = new/obj/structure/bed/medical/emergency(silicon_bed) + qdel(src) //"Load" + return ITEM_INTERACT_SUCCESS - else - return ..() /obj/item/emergency_bed/attack_self(mob/user) deploy_bed(user, user.loc) diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 701d1d4e58c..3204f87c1f7 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -40,12 +40,12 @@ QDEL_NULL(burning_loop) . = ..() -/obj/structure/bonfire/attackby(obj/item/used_item, mob/living/user, list/modifiers, list/attack_modifiers) - if(istype(used_item, /obj/item/stack/rods) && !can_buckle && !grill) - var/obj/item/stack/rods/rods = used_item +/obj/structure/bonfire/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/stack/rods) && !can_buckle && !grill) + var/obj/item/stack/rods/rods = tool var/choice = tgui_alert(user, "What would you like to construct?", "Bonfire", list("Stake","Grill")) if(isnull(choice)) - return + return ITEM_INTERACT_BLOCKING rods.use(1) switch(choice) if("Stake") @@ -55,28 +55,36 @@ var/mutable_appearance/rod_underlay = mutable_appearance('icons/obj/service/hydroponics/equipment.dmi', "bonfire_rod") rod_underlay.pixel_z = 16 underlays += rod_underlay + return ITEM_INTERACT_SUCCESS + if("Grill") grill = TRUE to_chat(user, span_notice("You add a grill to \the [src].")) add_overlay("bonfire_grill") - else - return ..() - if(used_item.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + return ITEM_INTERACT_SUCCESS + + + if(tool.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) start_burning() + return ITEM_INTERACT_SUCCESS + if(grill) - if(istype(used_item, /obj/item/melee/roastingstick)) - return FALSE - if(!user.combat_mode && !(used_item.item_flags & ABSTRACT)) - if(user.temporarilyRemoveItemFromInventory(used_item)) - used_item.forceMove(get_turf(src)) - //Center the icon where the user clicked. - if(!LAZYACCESS(modifiers, ICON_X) || !LAZYACCESS(modifiers, ICON_Y)) - return - //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) - used_item.pixel_x = used_item.base_pixel_x + clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X/2), ICON_SIZE_X/2) - used_item.pixel_y = used_item.base_pixel_y + clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y/2), ICON_SIZE_Y/2) - else - return ..() + if(istype(tool, /obj/item/melee/roastingstick)) + return ITEM_INTERACT_BLOCKING + if(user.combat_mode || (tool.item_flags & ABSTRACT)) + return NONE + if(!user.temporarilyRemoveItemFromInventory(tool)) + return ITEM_INTERACT_BLOCKING + tool.forceMove(get_turf(src)) + //Center the icon where the user clicked. + if(!LAZYACCESS(modifiers, ICON_X) || !LAZYACCESS(modifiers, ICON_Y)) + return ITEM_INTERACT_SUCCESS + //Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf) + tool.pixel_x = tool.base_pixel_x + clamp(text2num(LAZYACCESS(modifiers, ICON_X)) - 16, -(ICON_SIZE_X/2), ICON_SIZE_X/2) + tool.pixel_y = tool.base_pixel_y + clamp(text2num(LAZYACCESS(modifiers, ICON_Y)) - 16, -(ICON_SIZE_Y/2), ICON_SIZE_Y/2) + return ITEM_INTERACT_SUCCESS + + return NONE /obj/structure/bonfire/attack_hand(mob/user, list/modifiers) . = ..() diff --git a/code/game/objects/structures/cannons/cannon.dm b/code/game/objects/structures/cannons/cannon.dm index bff6a32ff69..a276bb022f7 100644 --- a/code/game/objects/structures/cannons/cannon.dm +++ b/code/game/objects/structures/cannons/cannon.dm @@ -54,62 +54,70 @@ default_unfasten_wrench(user, tool) return ITEM_INTERACT_SUCCESS -/obj/structure/cannon/attackby(obj/item/used_item, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/cannon/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(charge_ignited) balloon_alert(user, "it's gonna fire!") - return - var/ignition_message = used_item.ignition_effect(src, user) + return ITEM_INTERACT_BLOCKING - if(istype(used_item, /obj/item/stack/cannonball)) + if(istype(tool, /obj/item/stack/cannonball)) if(loaded_cannonball) balloon_alert(user, "already loaded!") - else - var/obj/item/stack/cannonball/cannoneers_balls = used_item - loaded_cannonball = new cannoneers_balls.type(src, 1) - loaded_cannonball.copy_evidences(cannoneers_balls) - balloon_alert(user, "loaded a [cannoneers_balls.singular_name]") - cannoneers_balls.use(1, transfer = TRUE) - return + return ITEM_INTERACT_BLOCKING - else if(ignition_message) + var/obj/item/stack/cannonball/cannoneers_balls = tool + loaded_cannonball = new cannoneers_balls.type(src, 1) + loaded_cannonball.copy_evidences(cannoneers_balls) + balloon_alert(user, "loaded a [cannoneers_balls.singular_name]") + cannoneers_balls.use(1, transfer = TRUE) + return ITEM_INTERACT_SUCCESS + + var/ignition_message = tool.ignition_effect(src, user) + + if(ignition_message) if(!reagents.has_reagent(/datum/reagent/gunpowder,charge_size) && !reagents.has_reagent(/datum/reagent/fuel,charge_size)) balloon_alert(user, "needs [reagents.maximum_volume]u of charge!") - return + return ITEM_INTERACT_BLOCKING + visible_message(ignition_message) user.log_message("fired a cannon", LOG_ATTACK) log_game("[key_name(user)] fired a cannon in [AREACOORD(src)]") addtimer(CALLBACK(src, PROC_REF(fire)), fire_delay) charge_ignited = TRUE - return + return ITEM_INTERACT_SUCCESS - else if(is_reagent_container(used_item)) - var/obj/item/reagent_containers/powder_keg = used_item + if(is_reagent_container(tool)) + var/obj/item/reagent_containers/powder_keg = tool if(!powder_keg.is_open_container()) - return ..() + return NONE // reagent containers transfer elsewhere in the chain, be free + if(istype(powder_keg, /obj/item/rag)) - return ..() + return NONE if(!powder_keg.reagents.total_volume) balloon_alert(user, "[powder_keg] is empty!") - return + return ITEM_INTERACT_BLOCKING + if(reagents.total_volume == reagents.maximum_volume) balloon_alert(user, "[src] is full!") - return + return ITEM_INTERACT_BLOCKING + var/has_enough_gunpowder = powder_keg.reagents.has_reagent(/datum/reagent/gunpowder, charge_size) var/has_enough_alt_fuel = powder_keg.reagents.has_reagent(/datum/reagent/fuel, charge_size) if(!has_enough_gunpowder && !has_enough_alt_fuel) balloon_alert(user, "[powder_keg] needs 15u of charge to load!") to_chat(user, span_warning("[powder_keg] doesn't have at least 15u of gunpowder to fill [src]!")) - return + return ITEM_INTERACT_BLOCKING + if(has_enough_gunpowder) powder_keg.reagents.trans_to(src, charge_size, target_id = /datum/reagent/gunpowder) balloon_alert(user, "[src] loaded with gunpowder") - return - if(has_enough_alt_fuel) - powder_keg.reagents.trans_to(src, charge_size, target_id = /datum/reagent/fuel) - balloon_alert(user, "[src] loaded with welding fuel") - return - ..() + return ITEM_INTERACT_SUCCESS + + //if(has_enough_alt_fuel) but we already know it does if we're here + powder_keg.reagents.trans_to(src, charge_size, target_id = /datum/reagent/fuel) + balloon_alert(user, "[src] loaded with welding fuel") + return ITEM_INTERACT_SUCCESS + return NONE /obj/structure/cannon/trash name = "trash cannon" diff --git a/code/game/objects/structures/curtains.dm b/code/game/objects/structures/curtains.dm index ec864ca5a86..fea411efac0 100644 --- a/code/game/objects/structures/curtains.dm +++ b/code/game/objects/structures/curtains.dm @@ -42,11 +42,11 @@ icon_state = "[icon_type]-[open ? "open" : "closed"]" return ..() -/obj/structure/curtain/attackby(obj/item/W, mob/user) - if (istype(W, /obj/item/toy/crayon)) - color = tgui_color_picker(user, "", "Choose Color", color) - else - return ..() +/obj/structure/curtain/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/toy/crayon)) + return NONE + color = tgui_color_picker(user, "", "Choose Color", color) + return ITEM_INTERACT_SUCCESS /obj/structure/curtain/wrench_act(mob/living/user, obj/item/tool) . = ..() diff --git a/code/game/objects/structures/detectiveboard.dm b/code/game/objects/structures/detectiveboard.dm index 91df15cc443..f49266993b0 100644 --- a/code/game/objects/structures/detectiveboard.dm +++ b/code/game/objects/structures/detectiveboard.dm @@ -40,34 +40,36 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/detectiveboard, 32) /// Attaching evidences: photo and papers -/obj/structure/detectiveboard/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(item, /obj/item/paper) || istype(item, /obj/item/photo)) - if(!cases.len) - to_chat(user, "There are no cases!") - return +/obj/structure/detectiveboard/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/paper) && !istype(tool, /obj/item/photo)) + return NONE + if(!cases.len) + to_chat(user, "There are no cases!") + return ITEM_INTERACT_BLOCKING - if(attaching_evidence) - to_chat(user, "You already attaching evidence!") - return - attaching_evidence = TRUE - var/name = tgui_input_text(user, "Please enter the evidence name", "Detective's Board", max_length = MAX_NAME_LEN) - if(!name) - name = item.name - var/desc = tgui_input_text(user, "Please enter the evidence description", "Detective's Board", max_length = MAX_DESC_LEN) - if(!desc) - desc = item.desc + if(attaching_evidence) + to_chat(user, "You already attaching evidence!") + return ITEM_INTERACT_BLOCKING - if(!user.transferItemToLoc(item, src)) - attaching_evidence = FALSE - return - cases[current_case].notices++ - var/datum/evidence/evidence = new (name, desc, item) - cases[current_case].evidences += evidence - to_chat(user, span_notice("You pin the [item] to the detective board.")) + attaching_evidence = TRUE + var/name = tgui_input_text(user, "Please enter the evidence name", "Detective's Board", max_length = MAX_NAME_LEN) + if(!name) + name = tool.name + var/desc = tgui_input_text(user, "Please enter the evidence description", "Detective's Board", max_length = MAX_DESC_LEN) + if(!desc) + desc = tool.desc + + if(!user.transferItemToLoc(tool, src)) attaching_evidence = FALSE - update_appearance(UPDATE_ICON) - return - return ..() + return ITEM_INTERACT_BLOCKING + + cases[current_case].notices++ + var/datum/evidence/evidence = new (name, desc, tool) + cases[current_case].evidences += evidence + to_chat(user, span_notice("You pin the [tool] to the detective board.")) + attaching_evidence = FALSE + update_appearance(UPDATE_ICON) + return ITEM_INTERACT_SUCCESS /obj/structure/detectiveboard/wrench_act_secondary(mob/living/user, obj/item/tool) . = ..() diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index efc44e195dd..096f1122022 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -125,54 +125,80 @@ . += "[initial(icon_state)]_closed" return -/obj/structure/displaycase/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers) - if(attacking_item.GetID() && !broken) - if(allowed(user)) - to_chat(user, span_notice("You [open ? "close":"open"] [src].")) - toggle_lock(user) - else +/obj/structure/displaycase/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(tool.GetID() && !broken) + if(!allowed(user)) to_chat(user, span_alert("Access denied.")) - else if(attacking_item.tool_behaviour == TOOL_WELDER && !user.combat_mode && !broken) - if(atom_integrity < max_integrity) - if(!attacking_item.tool_start_check(user, amount=1)) - return + return ITEM_INTERACT_BLOCKING - to_chat(user, span_notice("You begin repairing [src]...")) - if(attacking_item.use_tool(src, user, 40, volume=50)) - atom_integrity = max_integrity - update_appearance() - to_chat(user, span_notice("You repair [src].")) - else - to_chat(user, span_warning("[src] is already in good condition!")) - return - else if(!alert && attacking_item.tool_behaviour == TOOL_CROWBAR) //Only applies to the lab cage and player made display cases - if(broken) - if(showpiece) - to_chat(user, span_warning("Remove the displayed object first!")) - else - to_chat(user, span_notice("You remove the destroyed case.")) - qdel(src) - else - to_chat(user, span_notice("You start to [open ? "close":"open"] [src]...")) - if(attacking_item.use_tool(src, user, 20)) - to_chat(user, span_notice("You [open ? "close":"open"] [src].")) - toggle_lock(user) - else if(open && !showpiece) - insert_showpiece(attacking_item, user) - return TRUE //cancel the attack chain, whether we successfully placed an item or not - else if(glass_fix && broken && istype(attacking_item, /obj/item/stack/sheet/glass)) - var/obj/item/stack/sheet/glass/glass_sheet = attacking_item + to_chat(user, span_notice("You [open ? "close":"open"] [src].")) + toggle_lock(user) + return ITEM_INTERACT_SUCCESS + + + if(open && !showpiece) + insert_showpiece(tool, user) + return ITEM_INTERACT_SUCCESS //cancel the attack chain, whether we successfully placed an item or not + + if(glass_fix && broken && istype(tool, /obj/item/stack/sheet/glass)) + var/obj/item/stack/sheet/glass/glass_sheet = tool if(glass_sheet.get_amount() < 2) to_chat(user, span_warning("You need two glass sheets to fix the case!")) - return + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You start fixing [src]...")) - if(do_after(user, 2 SECONDS, target = src)) - glass_sheet.use(2) - broken = FALSE - atom_integrity = max_integrity - update_appearance() - else - return ..() + if(!do_after(user, 2 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + + glass_sheet.use(2) + broken = FALSE + atom_integrity = max_integrity + update_appearance() + return ITEM_INTERACT_SUCCESS + + return NONE + +/obj/structure/displaycase/welder_act(mob/living/user, obj/item/tool) + if(user.combat_mode || broken) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(atom_integrity == max_integrity) + to_chat(user, span_warning("[src] is already in good condition!")) + return ITEM_INTERACT_BLOCKING + + if(!tool.tool_start_check(user, amount=1)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You begin repairing [src]...")) + if(!tool.use_tool(src, user, 40, volume=50)) + return ITEM_INTERACT_BLOCKING + + atom_integrity = max_integrity + update_appearance() + to_chat(user, span_notice("You repair [src].")) + return ITEM_INTERACT_SUCCESS + +/obj/structure/displaycase/crowbar_act(mob/living/user, obj/item/tool) + if(alert) //Only applies to the lab cage and player made display cases + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(broken) + if(showpiece) + to_chat(user, span_warning("Remove the displayed object first!")) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You remove the destroyed case.")) + qdel(src) + return ITEM_INTERACT_SUCCESS + + to_chat(user, span_notice("You start to [open ? "close":"open"] [src]...")) + if(!tool.use_tool(src, user, 20)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You [open ? "close":"open"] [src].")) + toggle_lock(user) + return ITEM_INTERACT_SUCCESS + ///Handles placing an item into the display case. Returns TRUE if the item failed to be placed inside the container, useful for descendants /obj/structure/displaycase/proc/insert_showpiece(obj/item/new_showpiece, mob/user) @@ -273,33 +299,40 @@ qdel(src) return ITEM_INTERACT_SUCCESS -/obj/structure/displaycase_chassis/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(attacking_item, /obj/item/electronics/airlock)) +/obj/structure/displaycase_chassis/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/electronics/airlock)) balloon_alert(user, "installing electronics...") - if(do_after(user, 3 SECONDS, target = src) && user.transferItemToLoc(attacking_item, src)) - electronics = attacking_item - balloon_alert(user, "electronics installed") - return + if(!do_after(user, 3 SECONDS, target = src) || !user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING - if(istype(attacking_item, /obj/item/stock_parts/card_reader)) - var/obj/item/stock_parts/card_reader/card_reader = attacking_item - balloon_alert(user, "adding [card_reader]...") - if(do_after(user, 2 SECONDS, target = src)) - qdel(card_reader) - make_final_result(display_type = /obj/structure/displaycase/forsale) - return + electronics = tool + balloon_alert(user, "electronics installed") + return ITEM_INTERACT_SUCCESS - if(istype(attacking_item, /obj/item/stack/sheet/glass)) - var/obj/item/stack/sheet/glass/glass_sheets = attacking_item + if(istype(tool, /obj/item/stock_parts/card_reader)) + balloon_alert(user, "adding [tool]...") + if(!do_after(user, 2 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + + qdel(tool) + make_final_result(display_type = /obj/structure/displaycase/forsale) + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/stack/sheet/glass)) + var/obj/item/stack/sheet/glass/glass_sheets = tool if(glass_sheets.get_amount() < 10) balloon_alert(user, "need 10 sheets!") - return + return ITEM_INTERACT_BLOCKING + balloon_alert(user, "adding glass...") - if(do_after(user, 2 SECONDS, target = src)) - glass_sheets.use(10) - make_final_result(display_type = /obj/structure/displaycase/noalert) - return - return ..() + if(!do_after(user, 2 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + + glass_sheets.use(10) + make_final_result(display_type = /obj/structure/displaycase/noalert) + return ITEM_INTERACT_SUCCESS + + return NONE ///Makes the final result of the chassis, then deletes itself. /obj/structure/displaycase_chassis/proc/make_final_result(obj/structure/displaycase/display_type) @@ -360,11 +393,11 @@ holographic_showpiece = TRUE update_appearance() -/obj/structure/displaycase/trophy/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(attacking_item, /obj/item/key/displaycase)) - toggle_historian_mode(user) - return - return ..() +/obj/structure/displaycase/trophy/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/key/displaycase)) + return ..() + toggle_historian_mode(user) + return ITEM_INTERACT_SUCCESS /obj/structure/displaycase/trophy/dump() if (showpiece) @@ -610,20 +643,25 @@ return TRUE . = TRUE -/obj/structure/displaycase/forsale/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - if(isidcard(attacking_item)) +/obj/structure/displaycase/forsale/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(isidcard(tool)) //Card Registration - var/obj/item/card/id/potential_acc = attacking_item + var/obj/item/card/id/potential_acc = tool if(!potential_acc.registered_account) to_chat(user, span_warning("This ID card has no account registered!")) - return - if(payments_acc == potential_acc.registered_account) - toggle_lock() - return - if(istype(attacking_item, /obj/item/modular_computer)) - return TRUE + return ITEM_INTERACT_BLOCKING + + if(payments_acc != potential_acc.registered_account) + return ITEM_INTERACT_BLOCKING + + toggle_lock() + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/modular_computer)) + return ITEM_INTERACT_BLOCKING + SStgui.update_uis(src) - return ..() + return ITEM_INTERACT_SUCCESS /obj/structure/displaycase/forsale/multitool_act(mob/living/user, obj/item/I) . = ..() diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 6a882a62114..e606729fbfa 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -83,176 +83,99 @@ if(created_name) . += span_notice("There is a small paper placard on the assembly, written on it is '[created_name]'.") -/obj/structure/door_assembly/attackby(obj/item/tool, mob/living/user, list/modifiers, list/attack_modifiers) - if((tool.tool_behaviour == TOOL_WELDER) && (mineral || glass || !anchored )) +/obj/structure/door_assembly/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(anchored && state == AIRLOCK_ASSEMBLY_NEEDS_WIRES && istype(tool, /obj/item/stack/cable_coil)) if(!tool.tool_start_check(user, amount=1)) - return - - if(mineral) - var/obj/item/stack/sheet/mineral/mineral_path = text2path("/obj/item/stack/sheet/mineral/[mineral]") - user.visible_message(span_notice("[user] welds the [mineral] plating off the airlock assembly."), span_notice("You start to weld the [mineral] plating off the airlock assembly...")) - if(tool.use_tool(src, user, 40, volume=50)) - to_chat(user, span_notice("You weld the [mineral] plating off.")) - new mineral_path(loc, 2) - var/obj/structure/door_assembly/PA = new previous_assembly(loc) - transfer_assembly_vars(src, PA) - - else if(glass) - user.visible_message(span_notice("[user] welds the glass panel out of the airlock assembly."), span_notice("You start to weld the glass panel out of the airlock assembly...")) - if(tool.use_tool(src, user, 40, volume=50)) - to_chat(user, span_notice("You weld the glass panel out.")) - if(heat_proof_finished) - new /obj/item/stack/sheet/rglass(get_turf(src)) - heat_proof_finished = FALSE - else - new /obj/item/stack/sheet/glass(get_turf(src)) - glass = 0 - else if(!anchored) - user.visible_message(span_warning("[user] disassembles the airlock assembly."), \ - span_notice("You start to disassemble the airlock assembly...")) - if(tool.use_tool(src, user, 40, volume=50)) - to_chat(user, span_notice("You disassemble the airlock assembly.")) - deconstruct(TRUE) - - else if(tool.tool_behaviour == TOOL_WRENCH) - if(!anchored ) - var/door_check = 1 - for(var/obj/machinery/door/D in loc) - if(!D.sub_door) - door_check = 0 - break - - if(door_check) - user.visible_message(span_notice("[user] secures the airlock assembly to the floor."), \ - span_notice("You start to secure the airlock assembly to the floor..."), \ - span_hear("You hear wrenching.")) - - if(tool.use_tool(src, user, 40, volume=100)) - if(anchored) - return - to_chat(user, span_notice("You secure the airlock assembly.")) - name = "secured airlock assembly" - set_anchored(TRUE) - else - to_chat(user, "There is another door here!") - - else - user.visible_message(span_notice("[user] unsecures the airlock assembly from the floor."), \ - span_notice("You start to unsecure the airlock assembly from the floor..."), \ - span_hear("You hear wrenching.")) - if(tool.use_tool(src, user, 40, volume=100)) - if(!anchored) - return - to_chat(user, span_notice("You unsecure the airlock assembly.")) - name = "airlock assembly" - set_anchored(FALSE) - - else if(istype(tool, /obj/item/stack/cable_coil) && state == AIRLOCK_ASSEMBLY_NEEDS_WIRES && anchored ) - if(!tool.tool_start_check(user, amount=1)) - return + return ITEM_INTERACT_BLOCKING user.visible_message(span_notice("[user] wires the airlock assembly."), \ span_notice("You start to wire the airlock assembly...")) - if(tool.use_tool(src, user, 40, amount=1)) - if(state != AIRLOCK_ASSEMBLY_NEEDS_WIRES) - return - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - to_chat(user, span_notice("You wire the airlock assembly.")) - name = "wired airlock assembly" + if(!tool.use_tool(src, user, 40, amount=1)) + return ITEM_INTERACT_BLOCKING - else if((tool.tool_behaviour == TOOL_WIRECUTTER) && state == AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS ) - user.visible_message(span_notice("[user] cuts the wires from the airlock assembly."), \ - span_notice("You start to cut the wires from the airlock assembly...")) + if(state != AIRLOCK_ASSEMBLY_NEEDS_WIRES) + return ITEM_INTERACT_BLOCKING - if(tool.use_tool(src, user, 40, volume=100)) - if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) - return - to_chat(user, span_notice("You cut the wires from the airlock assembly.")) - new/obj/item/stack/cable_coil(get_turf(user), 1) - state = AIRLOCK_ASSEMBLY_NEEDS_WIRES - name = "secured airlock assembly" + state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS + to_chat(user, span_notice("You wire the airlock assembly.")) + name = "wired airlock assembly" + update_name() + update_appearance() + return ITEM_INTERACT_SUCCESS - else if(istype(tool, /obj/item/electronics/airlock) && state == AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS ) + if(state == AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS && istype(tool, /obj/item/electronics/airlock)) tool.play_tool_sound(src, 100) user.visible_message(span_notice("[user] installs the electronics into the airlock assembly."), \ span_notice("You start to install electronics into the airlock assembly...")) - if(do_after(user, 4 SECONDS, target = src)) - if( state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS ) - return - if(!user.transferItemToLoc(tool, src)) - return + if(!do_after(user, 4 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING - to_chat(user, span_notice("You install the airlock electronics.")) - state = AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER - name = "near finished airlock assembly" - electronics = tool + if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) + return ITEM_INTERACT_BLOCKING + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING - else if((tool.tool_behaviour == TOOL_CROWBAR) && state == AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER ) - user.visible_message(span_notice("[user] removes the electronics from the airlock assembly."), \ - span_notice("You start to remove electronics from the airlock assembly...")) + to_chat(user, span_notice("You install the airlock electronics.")) + state = AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER + name = "near finished airlock assembly" + electronics = tool + update_name() + update_appearance() + return ITEM_INTERACT_SUCCESS - if(tool.use_tool(src, user, 40, volume=100)) - if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - return - to_chat(user, span_notice("You remove the airlock electronics.")) - state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS - name = "wired airlock assembly" - var/obj/item/electronics/airlock/ae - if (!electronics) - ae = new/obj/item/electronics/airlock( loc ) - else - ae = electronics - electronics = null - ae.forceMove(src.loc) - - else if(istype(tool, /obj/item/stack/sheet)) + if(istype(tool, /obj/item/stack/sheet)) var/obj/item/stack/sheet/sheet = tool if(!glass && (istype(sheet, /obj/item/stack/sheet/rglass) || istype(sheet, /obj/item/stack/sheet/glass))) if(noglass) to_chat(user, span_warning("You cannot add [sheet] to [src]!")) - return + return ITEM_INTERACT_BLOCKING playsound(src, 'sound/items/tools/crowbar.ogg', 100, TRUE) user.visible_message(span_notice("[user] adds [sheet.name] to the airlock assembly."), \ span_notice("You start to install [sheet.name] into the airlock assembly...")) - if(do_after(user, 4 SECONDS, target = src)) - if(sheet.get_amount() < 1 || glass) - return - if(sheet.type == /obj/item/stack/sheet/rglass) - to_chat(user, span_notice("You install [sheet.name] windows into the airlock assembly.")) - heat_proof_finished = 1 //reinforced glass makes the airlock heat-proof - name = "near finished heat-proofed window airlock assembly" - else - to_chat(user, span_notice("You install regular glass windows into the airlock assembly.")) - name = "near finished window airlock assembly" - sheet.use(1) - glass = TRUE - return + if(!do_after(user, 4 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + if(sheet.get_amount() < 1 || glass) + return ITEM_INTERACT_BLOCKING + if(sheet.type == /obj/item/stack/sheet/rglass) + to_chat(user, span_notice("You install [sheet.name] windows into the airlock assembly.")) + heat_proof_finished = TRUE //reinforced glass makes the airlock heat-proof + name = "near finished heat-proofed window airlock assembly" + else + to_chat(user, span_notice("You install regular glass windows into the airlock assembly.")) + name = "near finished window airlock assembly" + sheet.use(1) + glass = TRUE + update_name() + update_appearance() + return ITEM_INTERACT_SUCCESS if(istype(sheet, /obj/item/stack/sheet/mineral) && sheet.construction_path_type) if(nomineral || mineral) to_chat(user, span_warning("You cannot add [sheet] to [src]!")) - return + return ITEM_INTERACT_BLOCKING - var/M = sheet.construction_path_type - var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]") + var/type_path_extension = sheet.construction_path_type + var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[type_path_extension]") if(!ispath(mineralassembly)) to_chat(user, span_warning("You cannot add [sheet] to [src]!")) - return + return ITEM_INTERACT_BLOCKING + if(sheet.get_amount() < 2) to_chat(user, span_warning("You need at least two sheets add a mineral cover!")) - return + return ITEM_INTERACT_BLOCKING playsound(src, 'sound/items/tools/crowbar.ogg', 100, TRUE) user.visible_message(span_notice("[user] adds [sheet.name] to the airlock assembly."), \ - span_notice("You start to install [sheet.name] into the airlock assembly...")) + span_notice("You start to install [sheet.name] into the airlock assembly...")) if(!do_after(user, 4 SECONDS, target = src) || sheet.get_amount() < 2 || mineral) - return - to_chat(user, span_notice("You install [M] plating into the airlock assembly.")) - sheet.use(2) - var/obj/structure/door_assembly/MA = new mineralassembly(loc) + return ITEM_INTERACT_BLOCKING - if(MA.noglass && glass) //in case the new door doesn't support glass. prevents the new one from reverting to a normal airlock after being constructed. + to_chat(user, span_notice("You install [type_path_extension] plating into the airlock assembly.")) + sheet.use(2) + var/obj/structure/door_assembly/replacement_assembly = new mineralassembly(loc) + + if(replacement_assembly.noglass && glass) //in case the new door doesn't support glass. prevents the new one from reverting to a normal airlock after being constructed. var/obj/item/stack/sheet/dropped_glass if(heat_proof_finished) dropped_glass = new /obj/item/stack/sheet/rglass(drop_location()) @@ -260,22 +183,163 @@ else dropped_glass = new /obj/item/stack/sheet/glass(drop_location()) glass = FALSE - to_chat(user, span_notice("As you finish, a [dropped_glass.singular_name] falls out of [MA]'s frame.")) + to_chat(user, span_notice("As you finish, a [dropped_glass.singular_name] falls out of [replacement_assembly]'s frame.")) - transfer_assembly_vars(src, MA, TRUE) + transfer_assembly_vars(src, replacement_assembly, TRUE) + return ITEM_INTERACT_SUCCESS - else if((tool.tool_behaviour == TOOL_SCREWDRIVER) && state == AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER ) - user.visible_message(span_notice("[user] finishes the airlock."), \ - span_notice("You start finishing the airlock...")) + return NONE - if(tool.use_tool(src, user, 40, volume=100)) - if(loc && state == AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) - to_chat(user, span_notice("You finish the airlock.")) - finish_door() - else - return ..() +/obj/structure/door_assembly/welder_act(mob/living/user, obj/item/tool) + if(!mineral && !glass && anchored) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(!tool.tool_start_check(user, amount=1)) + return ITEM_INTERACT_BLOCKING + + if(mineral) + var/obj/item/stack/sheet/mineral/mineral_path = text2path("/obj/item/stack/sheet/mineral/[mineral]") + user.visible_message(span_notice("[user] welds the [mineral] plating off the airlock assembly."), span_notice("You start to weld the [mineral] plating off the airlock assembly...")) + if(!tool.use_tool(src, user, 40, volume=50)) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You weld the [mineral] plating off.")) + new mineral_path(loc, 2) + var/obj/structure/door_assembly/PA = new previous_assembly(loc) + transfer_assembly_vars(src, PA) + update_name() + update_appearance() + return ITEM_INTERACT_SUCCESS + + if(glass) + user.visible_message(span_notice("[user] welds the glass panel out of the airlock assembly."), \ + span_notice("You start to weld the glass panel out of the airlock assembly...")) + if(!tool.use_tool(src, user, 40, volume=50)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You weld the glass panel out.")) + if(heat_proof_finished) + new /obj/item/stack/sheet/rglass(get_turf(src)) + heat_proof_finished = FALSE + else + new /obj/item/stack/sheet/glass(get_turf(src)) + glass = FALSE + update_name() + update_appearance() + return ITEM_INTERACT_SUCCESS + + if(!anchored) + user.visible_message(span_warning("[user] disassembles the airlock assembly."), \ + span_notice("You start to disassemble the airlock assembly...")) + if(!tool.use_tool(src, user, 40, volume=50)) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You disassemble the airlock assembly.")) + deconstruct(TRUE) + return ITEM_INTERACT_SUCCESS + // no return NONE at end because it's not possible we end up here + +/obj/structure/door_assembly/wrench_act(mob/living/user, obj/item/tool) + if(anchored) + user.visible_message(span_notice("[user] unsecures the airlock assembly from the floor."), \ + span_notice("You start to unsecure the airlock assembly from the floor..."), \ + span_hear("You hear wrenching.")) + if(!tool.use_tool(src, user, 40, volume=100)) + return ITEM_INTERACT_BLOCKING + + if(!anchored) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You unsecure the airlock assembly.")) + name = "airlock assembly" + set_anchored(FALSE) + update_name() + update_appearance() + return ITEM_INTERACT_SUCCESS + + var/door_check = FALSE + for(var/obj/machinery/door/competitor in loc) + if(!competitor.sub_door) + door_check = TRUE + break + + if(door_check) + to_chat(user, "There is another door here!") + return ITEM_INTERACT_BLOCKING + + user.visible_message(span_notice("[user] secures the airlock assembly to the floor."), \ + span_notice("You start to secure the airlock assembly to the floor..."), \ + span_hear("You hear wrenching.")) + + if(!tool.use_tool(src, user, 40, volume=100)) + return ITEM_INTERACT_BLOCKING + + if(anchored) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You secure the airlock assembly.")) + name = "secured airlock assembly" + set_anchored(TRUE) update_name() update_appearance() + return ITEM_INTERACT_SUCCESS + +/obj/structure/door_assembly/wirecutter_act(mob/living/user, obj/item/tool) + if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) + return ITEM_INTERACT_SKIP_TO_ATTACK + user.visible_message(span_notice("[user] cuts the wires from the airlock assembly."), \ + span_notice("You start to cut the wires from the airlock assembly...")) + + if(!tool.use_tool(src, user, 40, volume=100)) + return ITEM_INTERACT_BLOCKING + if(state != AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You cut the wires from the airlock assembly.")) + new/obj/item/stack/cable_coil(get_turf(user), 1) + state = AIRLOCK_ASSEMBLY_NEEDS_WIRES + name = "secured airlock assembly" + update_name() + update_appearance() + return ITEM_INTERACT_SUCCESS + +/obj/structure/door_assembly/crowbar_act(mob/living/user, obj/item/tool) + if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) + return ITEM_INTERACT_SKIP_TO_ATTACK + user.visible_message(span_notice("[user] removes the electronics from the airlock assembly."), \ + span_notice("You start to remove electronics from the airlock assembly...")) + + if(!tool.use_tool(src, user, 40, volume=100)) + return ITEM_INTERACT_BLOCKING + + if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You remove the airlock electronics.")) + state = AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS + name = "wired airlock assembly" + var/obj/item/electronics/airlock/ae + if (!electronics) + ae = new/obj/item/electronics/airlock(loc) + else + ae = electronics + electronics = null + ae.forceMove(src.loc) + update_name() + update_appearance() + return ITEM_INTERACT_SUCCESS + +/obj/structure/door_assembly/screwdriver_act(mob/living/user, obj/item/tool) + if(state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) + return ITEM_INTERACT_SKIP_TO_ATTACK + + user.visible_message(span_notice("[user] finishes the airlock."), \ + span_notice("You start finishing the airlock...")) + if(!tool.use_tool(src, user, 40, volume=100)) + return ITEM_INTERACT_BLOCKING + + if(!loc || state != AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You finish the airlock.")) + finish_door() + return ITEM_INTERACT_SUCCESS /obj/structure/door_assembly/proc/finish_door() var/obj/machinery/door/airlock/door diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index f3e56bad87e..38ad4061e1d 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -8,14 +8,14 @@ anchored = TRUE custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 10) -/obj/structure/dresser/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers) - if(I.tool_behaviour == TOOL_WRENCH) - to_chat(user, span_notice("You begin to [anchored ? "unwrench" : "wrench"] [src].")) - if(I.use_tool(src, user, 20, volume=50)) - to_chat(user, span_notice("You successfully [anchored ? "unwrench" : "wrench"] [src].")) - set_anchored(!anchored) - else - return ..() +/obj/structure/dresser/wrench_act(mob/living/user, obj/item/tool) + to_chat(user, span_notice("You begin to [anchored ? "unwrench" : "wrench"] [src].")) + if(!tool.use_tool(src, user, 20, volume=50)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You successfully [anchored ? "unwrench" : "wrench"] [src].")) + set_anchored(!anchored) + return ITEM_INTERACT_SUCCESS /obj/structure/dresser/atom_deconstruct(disassembled = TRUE) new /obj/item/stack/sheet/mineral/wood(drop_location(), 10) diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index ffe4252f6ef..b6c1cf715b1 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -17,11 +17,9 @@ shock_flags = (SHOCK_NOGLOVES)\ ) -/obj/structure/chair/e_chair/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) - if(W.tool_behaviour == TOOL_WRENCH) - var/obj/structure/chair/C = new /obj/structure/chair(loc) - W.play_tool_sound(src) - C.setDir(dir) - qdel(src) - return - . = ..() +/obj/structure/chair/e_chair/wrench_act(mob/living/user, obj/item/tool) + var/obj/structure/chair/non_electric_chair = new /obj/structure/chair(loc) + tool.play_tool_sound(src) + non_electric_chair.setDir(dir) + qdel(src) + return ITEM_INTERACT_SUCCESS diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 785ad0ab3f8..6b66b2e5488 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -120,16 +120,16 @@ /obj/structure/falsewall/welder_act(mob/living/user, obj/item/tool) - if(tool.use_tool(src, user, 0 SECONDS, volume=50)) - dismantle(user, TRUE) - return ITEM_INTERACT_SUCCESS - return + if(!tool.use_tool(src, user, 0 SECONDS, volume=50)) + return ITEM_INTERACT_BLOCKING + dismantle(user, TRUE) + return ITEM_INTERACT_SUCCESS -/obj/structure/falsewall/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) - if(!opening) - return ..() - to_chat(user, span_warning("You must wait until the door has stopped moving!")) - return +/obj/structure/falsewall/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(opening) + to_chat(user, span_warning("You must wait until the door has stopped moving!")) + return ITEM_INTERACT_BLOCKING // honest to god no idea what the point of this blocker is, I'm just the messenger + return NONE /obj/structure/falsewall/proc/dismantle(mob/user, disassembled=TRUE, obj/item/tool = null) user.visible_message(span_notice("[user] dismantles the false wall."), span_notice("You dismantle the false wall.")) @@ -176,10 +176,12 @@ /obj/structure/falsewall/reinforced/examine_status(mob/user) return span_notice("The outer grille is fully intact.") -/obj/structure/falsewall/reinforced/attackby(obj/item/tool, mob/user) - ..() - if(tool.tool_behaviour == TOOL_WIRECUTTER) - dismantle(user, TRUE, tool) +/obj/structure/falsewall/reinforced/wirecutter_act(mob/living/user, obj/item/tool) + dismantle(user, TRUE, tool) + return ITEM_INTERACT_SUCCESS + +/obj/structure/falsewall/reinforced/welder_act(mob/living/user, obj/item/tool) + return NONE /* * Uranium Falsewalls diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm index f2f9d138df8..05c0b298436 100644 --- a/code/game/objects/structures/fence.dm +++ b/code/game/objects/structures/fence.dm @@ -58,37 +58,38 @@ icon_state = "straight_cut3" hole_size = LARGE_HOLE -/obj/structure/fence/attackby(obj/item/W, mob/user) - if(W.tool_behaviour == TOOL_WIRECUTTER) - if(!cuttable) - to_chat(user, span_warning("This section of the fence can't be cut!")) - return - if(invulnerable) - to_chat(user, span_warning("This fence is too strong to cut through!")) - return - var/current_stage = hole_size - if(current_stage >= MAX_HOLE_SIZE) - to_chat(user, span_warning("This fence has too much cut out of it already!")) - return +/obj/structure/fence/wirecutter_act(mob/living/user, obj/item/tool) + if(!cuttable) + to_chat(user, span_warning("This section of the fence can't be cut!")) + return ITEM_INTERACT_BLOCKING - user.visible_message(span_danger("\The [user] starts cutting through \the [src] with \the [W]."),\ - span_danger("You start cutting through \the [src] with \the [W].")) + if(invulnerable) + to_chat(user, span_warning("This fence is too strong to cut through!")) + return ITEM_INTERACT_BLOCKING - if(do_after(user, CUT_TIME*W.toolspeed, target = src)) - if(current_stage == hole_size) - switch(++hole_size) - if(MEDIUM_HOLE) - visible_message(span_notice("\The [user] cuts into \the [src] some more.")) - to_chat(user, span_info("You could probably fit yourself through that hole now. Although climbing through would be much faster if you made it even bigger.")) - AddElement(/datum/element/climbable) - if(LARGE_HOLE) - visible_message(span_notice("\The [user] completely cuts through \the [src].")) - to_chat(user, span_info("The hole in \the [src] is now big enough to walk through.")) - RemoveElement(/datum/element/climbable) + var/current_stage = hole_size + if(current_stage >= MAX_HOLE_SIZE) + to_chat(user, span_warning("This fence has too much cut out of it already!")) + return ITEM_INTERACT_BLOCKING - update_cut_status() + user.visible_message(span_danger("\The [user] starts cutting through \the [src] with \the [tool]."),\ + span_danger("You start cutting through \the [src] with \the [tool].")) - return TRUE + if(!tool.use_tool(src, user, CUT_TIME)) + return ITEM_INTERACT_BLOCKING + if(current_stage != hole_size) + return ITEM_INTERACT_BLOCKING + switch(++hole_size) + if(MEDIUM_HOLE) + visible_message(span_notice("\The [user] cuts into \the [src] some more.")) + to_chat(user, span_info("You could probably fit yourself through that hole now. Although climbing through would be much faster if you made it even bigger.")) + AddElement(/datum/element/climbable) + if(LARGE_HOLE) + visible_message(span_notice("\The [user] completely cuts through \the [src].")) + to_chat(user, span_info("The hole in \the [src] is now big enough to walk through.")) + RemoveElement(/datum/element/climbable) + update_cut_status() + return ITEM_INTERACT_SUCCESS /obj/structure/fence/proc/update_cut_status() if(!cuttable) diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index 44aa56d6088..af406342726 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -47,45 +47,66 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet, 32) QDEL_NULL(held_item) return ..() -/obj/structure/fireaxecabinet/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers) - if(iscyborg(user) || attacking_item.tool_behaviour == unlocking_tool_behavior) +/obj/structure/fireaxecabinet/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(iscyborg(user) || tool.tool_behaviour == unlocking_tool_behavior) toggle_lock(user) - else if(attacking_item.tool_behaviour == TOOL_WELDER && !user.combat_mode && !broken) - if(atom_integrity < max_integrity) - if(!attacking_item.tool_start_check(user, amount = 2)) - return - balloon_alert(user, "repairing...") - if(attacking_item.use_tool(src, user, 4 SECONDS, volume= 50, amount = 2)) - repair_damage(max_integrity - get_integrity()) - update_appearance() - balloon_alert(user, "repaired") - else - balloon_alert(user, "already repaired!") - return - else if(istype(attacking_item, /obj/item/stack/sheet/glass) && broken) - var/obj/item/stack/sheet/glass/glass_stack = attacking_item + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/stack/sheet/glass) && broken) + var/obj/item/stack/sheet/glass/glass_stack = tool if(glass_stack.get_amount() < 2) balloon_alert(user, "need more glass!") - return + return ITEM_INTERACT_BLOCKING + balloon_alert(user, "repairing") - if(do_after(user, 2 SECONDS, target = src) && glass_stack.use(2)) - broken = FALSE - repair_damage(max_integrity - get_integrity()) - update_appearance() - else if(open || broken) - if(istype(attacking_item, item_path) && !held_item) - if(HAS_TRAIT(attacking_item, TRAIT_WIELDED)) - balloon_alert(user, "unwield it!") - return - if(!user.transferItemToLoc(attacking_item, src)) - return - held_item = attacking_item - update_appearance() - return - else if(!broken) - toggle_open() - else - return ..() + if(!glass_stack.use_tool(src, user, 2 SECONDS, 2)) + return ITEM_INTERACT_BLOCKING + + broken = FALSE + repair_damage(max_integrity - get_integrity()) + update_appearance() + return ITEM_INTERACT_SUCCESS + + if(open || broken) + if(!istype(tool, item_path) || held_item) + if(!broken) + toggle_open() // Unsure why this is desired behaviour + return ITEM_INTERACT_SUCCESS + return ITEM_INTERACT_BLOCKING + + if(HAS_TRAIT(tool, TRAIT_WIELDED)) + balloon_alert(user, "unwield it!") + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + held_item = tool + update_appearance() + return ITEM_INTERACT_SUCCESS + + return NONE + +/obj/structure/fireaxecabinet/welder_act(mob/living/user, obj/item/tool) + if(user.combat_mode || broken) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(atom_integrity == max_integrity) + balloon_alert(user, "already repaired!") + return ITEM_INTERACT_BLOCKING + + if(!tool.tool_start_check(user, amount = 2)) + return ITEM_INTERACT_BLOCKING + + balloon_alert(user, "repairing...") + if(!tool.use_tool(src, user, 4 SECONDS, volume= 50, amount = 2)) + return ITEM_INTERACT_BLOCKING + + repair_damage(max_integrity - get_integrity()) + update_appearance() + balloon_alert(user, "repaired") + return ITEM_INTERACT_SUCCESS + /obj/structure/fireaxecabinet/Exited(atom/movable/gone, direction) if(gone == held_item) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index d46b7e133f4..f9fb64b8247 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -49,47 +49,50 @@ /// Flags for the flora to determine what kind of sound to play when it gets hit var/flora_flags = NONE -/obj/structure/flora/attackby(obj/item/used_item, mob/living/user, list/modifiers, list/attack_modifiers) +/obj/structure/flora/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(user.combat_mode) - return ..() + return NONE + if(flags_1 & HOLOGRAM_1) balloon_alert(user, "it goes right through!") - return ..() - if(can_uproot && used_item.tool_behaviour == TOOL_SHOVEL) + return ITEM_INTERACT_BLOCKING + + if(can_uproot && tool.tool_behaviour == TOOL_SHOVEL) if(uprooted) user.visible_message(span_notice("[user] starts to replant [src]..."), - span_notice("You start to replant [src]...")) + span_notice("You start to replant [src]...")) else user.visible_message(span_notice("[user] starts to uproot [src]..."), - span_notice("You start to uproot [src]...")) - used_item.play_tool_sound(src, 50) + span_notice("You start to uproot [src]...")) + tool.play_tool_sound(src, 50) if(!do_after(user, harvest_time, src)) - return + return ITEM_INTERACT_BLOCKING if(uprooted) user.visible_message(span_notice("[user] replants [src]."), - span_notice("You replant [src].")) + span_notice("You replant [src].")) replant(user) else user.visible_message(span_notice("[user] uproots [src]."), - span_notice("You uproot [src].")) + span_notice("You uproot [src].")) uproot(user) - used_item.play_tool_sound(src, 50) - return + tool.play_tool_sound(src, 50) + return ITEM_INTERACT_SUCCESS - if(!can_harvest(user, used_item)) - return ..() + if(!can_harvest(user, tool)) + return NONE user.visible_message(span_notice("[user] starts to [harvest_verb] [src]..."), - span_notice("You start to [harvest_verb] [src] with [used_item]...")) - play_attack_sound(used_item.force) - if(!do_after(user, harvest_time * used_item.toolspeed, src)) - return - visible_message(span_notice("[user] [harvest_verb][harvest_verb_suffix] [src]."), - ignored_mobs = list(user)) - play_attack_sound(used_item.force) + span_notice("You start to [harvest_verb] [src] with [tool]...")) + play_attack_sound(tool.force) + if(!do_after(user, harvest_time * tool.toolspeed, src)) + return ITEM_INTERACT_BLOCKING + visible_message(span_notice("[user] [harvest_verb][harvest_verb_suffix] [src]."), + span_notice("You [harvest_verb] [src].")) + play_attack_sound(tool.force) if(harvest(user)) after_harvest(user) + return ITEM_INTERACT_SUCCESS /obj/structure/flora/attack_hand(mob/user, list/modifiers) . = ..() diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm index 1ce124dc3c3..47b3692b239 100644 --- a/code/game/objects/structures/fluff.dm +++ b/code/game/objects/structures/fluff.dm @@ -14,17 +14,19 @@ ///If true, the structure can be deconstructed into a metal sheet with a wrench. var/deconstructible = TRUE -/obj/structure/fluff/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers) - if(I.tool_behaviour == TOOL_WRENCH && deconstructible) - user.visible_message(span_notice("[user] starts disassembling [src]..."), span_notice("You start disassembling [src]...")) - I.play_tool_sound(src) - if(I.use_tool(src, user, 50)) - user.visible_message(span_notice("[user] disassembles [src]!"), span_notice("You break down [src] into scrap metal.")) - playsound(user, 'sound/items/deconstruct.ogg', 50, TRUE) - new/obj/item/stack/sheet/iron(drop_location()) - qdel(src) - return - ..() +/obj/structure/fluff/wrench_act(mob/living/user, obj/item/tool) + if(!deconstructible) + return ITEM_INTERACT_SKIP_TO_ATTACK + user.visible_message(span_notice("[user] starts disassembling [src]..."), \ + span_notice("You start disassembling [src]...")) + tool.play_tool_sound(src) + if(!tool.use_tool(src, user, 50)) + return ITEM_INTERACT_BLOCKING + user.visible_message(span_notice("[user] disassembles [src]!"), span_notice("You break down [src] into scrap metal.")) + playsound(user, 'sound/items/deconstruct.ogg', 50, TRUE) + new/obj/item/stack/sheet/iron(drop_location()) + qdel(src) + return ITEM_INTERACT_SUCCESS /** * Empty terrariums are created when a preserved terrarium in a lavaland seed vault is activated. diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 77e80e95dc4..84caad3e780 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -231,69 +231,79 @@ span_notice("You [anchored ? "fasten [src] to" : "unfasten [src] from"] the floor.")) return ITEM_INTERACT_SUCCESS -/obj/structure/grille/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/grille/item_interaction(mob/living/user, obj/item/tool, list/modifiers) user.changeNext_move(CLICK_CD_MELEE) - if(istype(W, /obj/item/stack/rods) && broken && do_after(user, 1 SECONDS, target = src)) + if(istype(tool, /obj/item/stack/rods) && broken) + if(!do_after(user, 1 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING if(shock(user, 90)) - return - var/obj/item/stack/rods/R = W + return ITEM_INTERACT_BLOCKING + var/obj/item/stack/rods/grille_to_be = tool user.visible_message(span_notice("[user] rebuilds the broken grille."), \ - span_notice("You rebuild the broken grille.")) + span_notice("You rebuild the broken grille.")) repair_grille() - R.use(1) - return TRUE + grille_to_be.use(1) + return ITEM_INTERACT_SUCCESS //window placing begin - else if(is_glass_sheet(W) || istype(W, /obj/item/stack/sheet/bronze)) - if (!broken) - var/obj/item/stack/ST = W - if (ST.get_amount() < 2) - to_chat(user, span_warning("You need at least two sheets of glass for that!")) - return - var/dir_to_set = SOUTHWEST - if(!anchored) - to_chat(user, span_warning("[src] needs to be fastened to the floor first!")) - return - for(var/obj/structure/window/WINDOW in loc) - to_chat(user, span_warning("There is already a window there!")) - return - if(!clear_tile(user)) - return - to_chat(user, span_notice("You start placing the window...")) - if(do_after(user,20, target = src)) - if(!src.loc || !anchored) //Grille broken or unanchored while waiting - return - for(var/obj/structure/window/WINDOW in loc) //Another window already installed on grille - return - if(!clear_tile(user)) - return - var/obj/structure/window/WD - if(istype(W, /obj/item/stack/sheet/plasmarglass)) - WD = new/obj/structure/window/reinforced/plasma/fulltile(drop_location()) //reinforced plasma window - else if(istype(W, /obj/item/stack/sheet/plasmaglass)) - WD = new/obj/structure/window/plasma/fulltile(drop_location()) //plasma window - else if(istype(W, /obj/item/stack/sheet/rglass)) - WD = new/obj/structure/window/reinforced/fulltile(drop_location()) //reinforced window - else if(istype(W, /obj/item/stack/sheet/titaniumglass)) - WD = new/obj/structure/window/reinforced/shuttle(drop_location()) - else if(istype(W, /obj/item/stack/sheet/plastitaniumglass)) - WD = new/obj/structure/window/reinforced/plasma/plastitanium(drop_location()) - else if(istype(W, /obj/item/stack/sheet/bronze)) - WD = new/obj/structure/window/bronze/fulltile(drop_location()) - else - WD = new/obj/structure/window/fulltile(drop_location()) //normal window - WD.setDir(dir_to_set) - WD.set_anchored(FALSE) - WD.state = 0 - ST.use(2) - to_chat(user, span_notice("You place [WD] on [src].")) - return + if(!broken && (is_glass_sheet(tool) || istype(tool, /obj/item/stack/sheet/bronze))) + var/obj/item/stack/to_spend = tool + if (to_spend.get_amount() < 2) + to_chat(user, span_warning("You need at least two sheets of glass for that!")) + return ITEM_INTERACT_BLOCKING + + var/dir_to_set = SOUTHWEST + if(!anchored) + to_chat(user, span_warning("[src] needs to be fastened to the floor first!")) + return ITEM_INTERACT_BLOCKING + + for(var/obj/structure/window/competitor in loc) + to_chat(user, span_warning("There is already a window there!")) + return ITEM_INTERACT_BLOCKING + + if(!clear_tile(user)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You start placing the window...")) + if(!do_after(user,20, target = src)) + return ITEM_INTERACT_BLOCKING + + if(!src.loc || !anchored) //Grille broken or unanchored while waiting + return ITEM_INTERACT_BLOCKING + + for(var/obj/structure/window/competitor in loc) //Another window already installed on grille + return ITEM_INTERACT_BLOCKING + + if(!clear_tile(user)) + return ITEM_INTERACT_BLOCKING + + var/obj/structure/window/building_window + if(istype(tool, /obj/item/stack/sheet/plasmarglass)) + building_window = new/obj/structure/window/reinforced/plasma/fulltile(drop_location()) //reinforced plasma window + else if(istype(tool, /obj/item/stack/sheet/plasmaglass)) + building_window = new/obj/structure/window/plasma/fulltile(drop_location()) //plasma window + else if(istype(tool, /obj/item/stack/sheet/rglass)) + building_window = new/obj/structure/window/reinforced/fulltile(drop_location()) //reinforced window + else if(istype(tool, /obj/item/stack/sheet/titaniumglass)) + building_window = new/obj/structure/window/reinforced/shuttle(drop_location()) + else if(istype(tool, /obj/item/stack/sheet/plastitaniumglass)) + building_window = new/obj/structure/window/reinforced/plasma/plastitanium(drop_location()) + else if(istype(tool, /obj/item/stack/sheet/bronze)) + building_window = new/obj/structure/window/bronze/fulltile(drop_location()) + else + building_window = new/obj/structure/window/fulltile(drop_location()) //normal window + building_window.setDir(dir_to_set) + building_window.set_anchored(FALSE) + building_window.state = 0 + to_spend.use(2) + to_chat(user, span_notice("You place [to_spend] on [src].")) + return ITEM_INTERACT_SUCCESS //window placing end - else if((W.obj_flags & CONDUCTS_ELECTRICITY) && shock(user, 70)) - return + if((tool.obj_flags & CONDUCTS_ELECTRICITY) && shock(user, 70)) + return ITEM_INTERACT_BLOCKING - return ..() + return NONE /obj/structure/grille/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 0615ea579da..aca4e872be6 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -63,18 +63,48 @@ LAZYINITLIST(buckled_mobs) . = ..() -/obj/structure/guillotine/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/stack/sheet/plasteel)) - to_chat(user, span_notice("You start repairing the guillotine with the plasteel...")) - if(blade_sharpness<10) - if(do_after(user,100,target=user)) - blade_sharpness = min(10,blade_sharpness+3) - I.use(1) - to_chat(user, span_notice("You repair the guillotine with the plasteel.")) - else - to_chat(user, span_notice("You stop repairing the guillotine with the plasteel.")) - else +/obj/structure/guillotine/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/stack/sheet/plasteel)) + if(blade_sharpness == GUILLOTINE_BLADE_MAX_SHARP) to_chat(user, span_warning("The guillotine is already fully repaired!")) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You start repairing the guillotine with the plasteel...")) + if(!do_after(user, 100, target = user)) + to_chat(user, span_notice("You stop repairing the guillotine with the plasteel.")) + return ITEM_INTERACT_BLOCKING + + blade_sharpness = min(GUILLOTINE_BLADE_MAX_SHARP, blade_sharpness+3) + tool.use(1) + to_chat(user, span_notice("You repair the guillotine with the plasteel.")) + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/sharpener)) + add_fingerprint(user) + if (blade_status == GUILLOTINE_BLADE_SHARPENING) + return ITEM_INTERACT_BLOCKING + + if (blade_status != GUILLOTINE_BLADE_RAISED) + to_chat(user, span_warning("You need to raise the blade in order to sharpen it!")) + return ITEM_INTERACT_BLOCKING + + if (blade_sharpness == GUILLOTINE_BLADE_MAX_SHARP) + to_chat(user, span_warning("The blade is sharp enough!")) + return ITEM_INTERACT_BLOCKING + + blade_status = GUILLOTINE_BLADE_SHARPENING + if(!do_after(user, 0.7 SECONDS, target = src)) + blade_status = GUILLOTINE_BLADE_RAISED + return ITEM_INTERACT_BLOCKING + + blade_status = GUILLOTINE_BLADE_RAISED + user.visible_message(span_notice("[user] sharpens the large blade of the guillotine."), + span_notice("You sharpen the large blade of the guillotine.")) + blade_sharpness += 1 + playsound(src, 'sound/items/unsheath.ogg', 100, TRUE) + return ITEM_INTERACT_SUCCESS + + return NONE /obj/structure/guillotine/examine(mob/user) . = ..() @@ -189,34 +219,6 @@ blade_status = GUILLOTINE_BLADE_DROPPED icon_state = "guillotine" -/obj/structure/guillotine/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) - if (istype(W, /obj/item/sharpener)) - add_fingerprint(user) - if (blade_status == GUILLOTINE_BLADE_SHARPENING) - return - - if (blade_status == GUILLOTINE_BLADE_RAISED) - if (blade_sharpness < GUILLOTINE_BLADE_MAX_SHARP) - blade_status = GUILLOTINE_BLADE_SHARPENING - if(do_after(user, 0.7 SECONDS, target = src)) - blade_status = GUILLOTINE_BLADE_RAISED - user.visible_message(span_notice("[user] sharpens the large blade of the guillotine."), - span_notice("You sharpen the large blade of the guillotine.")) - blade_sharpness += 1 - playsound(src, 'sound/items/unsheath.ogg', 100, TRUE) - return - else - blade_status = GUILLOTINE_BLADE_RAISED - return - else - to_chat(user, span_warning("The blade is sharp enough!")) - return - else - to_chat(user, span_warning("You need to raise the blade in order to sharpen it!")) - return - else - return ..() - /obj/structure/guillotine/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) if (!anchored) to_chat(usr, span_warning("[src] needs to be wrenched to the floor!")) diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm index f1894b1f7aa..d33eab136b8 100644 --- a/code/game/objects/structures/guncase.dm +++ b/code/game/objects/structures/guncase.dm @@ -31,24 +31,27 @@ . += new /mutable_appearance(gun_overlay) . += "[icon_state]_[open ? "open" : "door"]" -/obj/structure/guncase/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers) +/obj/structure/guncase/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(iscyborg(user) || isalien(user)) - return - if(istype(I, gun_category) && open) - if(LAZYLEN(contents) < capacity) - if(!user.transferItemToLoc(I, src)) - return - to_chat(user, span_notice("You place [I] in [src].")) - update_appearance() - else + return NONE + if(istype(tool, gun_category) && open) + if(LAZYLEN(contents) == capacity) to_chat(user, span_warning("[src] is full.")) - return + return ITEM_INTERACT_BLOCKING - else if(!user.combat_mode) + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You place [tool] in [src].")) + update_appearance() + return ITEM_INTERACT_SUCCESS + + if(!user.combat_mode) open = !open update_appearance() - else - return ..() + return ITEM_INTERACT_SUCCESS + + return NONE /obj/structure/guncase/attack_hand(mob/user, list/modifiers) . = ..() @@ -62,6 +65,13 @@ open = !open update_appearance() +/obj/structure/guncase/attack_hand_secondary(mob/user, list/modifiers) + if(iscyborg(user) || isalien(user)) + return ..() + open = !open + update_appearance() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + /** * show_menu: Shows a radial menu to a user consisting of an available weaponry for taking * diff --git a/code/game/objects/structures/janitor.dm b/code/game/objects/structures/janitor.dm index b0b194d6f1d..4fef894dfb6 100644 --- a/code/game/objects/structures/janitor.dm +++ b/code/game/objects/structures/janitor.dm @@ -28,30 +28,22 @@ return . -/obj/structure/mop_bucket/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers) - if(istype(weapon, /obj/item/reagent_containers)) - update_appearance(UPDATE_OVERLAYS) - return FALSE // skip attack animation when refilling cart - - return ..() - -/obj/structure/mop_bucket/attackby_secondary(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers) - if(istype(weapon, /obj/item/mop)) - if(weapon.reagents.total_volume >= weapon.reagents.maximum_volume) +/obj/structure/mop_bucket/item_interaction_secondary(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/mop)) + if(tool.reagents.total_volume >= tool.reagents.maximum_volume) balloon_alert(user, "already soaked!") - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ITEM_INTERACT_BLOCKING + if(!CART_HAS_MINIMUM_REAGENT_VOLUME) balloon_alert(user, "empty!") - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - reagents.trans_to(weapon, weapon.reagents.maximum_volume, transferred_by = user) + return ITEM_INTERACT_BLOCKING + + reagents.trans_to(tool, tool.reagents.maximum_volume, transferred_by = user) balloon_alert(user, "doused mop") playsound(src, 'sound/effects/slosh.ogg', 25, vary = TRUE) + return ITEM_INTERACT_SUCCESS - if(istype(weapon, /obj/item/reagent_containers) || istype(weapon, /obj/item/mop)) - update_appearance(UPDATE_OVERLAYS) - return SECONDARY_ATTACK_CONTINUE_CHAIN // skip attack animations when refilling cart - - return SECONDARY_ATTACK_CONTINUE_CHAIN + return NONE /obj/structure/mop_bucket/update_overlays() . = ..() @@ -182,55 +174,77 @@ return . || NONE -/obj/structure/mop_bucket/janitorialcart/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(attacking_item, /obj/item/mop)) +/obj/structure/mop_bucket/janitorialcart/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/mop)) if(mymop) balloon_alert(user, "already has \a [mymop]!") - else if(user.transferItemToLoc(attacking_item, src)) - balloon_alert(user, "placed [attacking_item]") - return + return ITEM_INTERACT_BLOCKING - if(istype(attacking_item, /obj/item/pushbroom)) + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + balloon_alert(user, "placed [tool]") + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/pushbroom)) if(mybroom) balloon_alert(user, "already has \a [mybroom]!") - else if(user.transferItemToLoc(attacking_item, src)) - balloon_alert(user, "placed [attacking_item]") - return + return ITEM_INTERACT_BLOCKING - if(istype(attacking_item, /obj/item/storage/bag/trash)) + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + balloon_alert(user, "placed [tool]") + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/storage/bag/trash)) if(mybag) balloon_alert(user, "already has \a [mybag]!") - return + return ITEM_INTERACT_BLOCKING - var/obj/item/storage/bag/trash/insert = attacking_item + var/obj/item/storage/bag/trash/insert = tool if(!insert.insertable) balloon_alert(user, "cannot be inserted!") - return + return ITEM_INTERACT_BLOCKING - if(user.transferItemToLoc(attacking_item, src)) - balloon_alert(user, "attached [attacking_item]") - return + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING - if(istype(attacking_item, /obj/item/reagent_containers/spray/cleaner)) + balloon_alert(user, "attached [tool]") + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/reagent_containers/spray/cleaner)) if(myspray) balloon_alert(user, "already has \a [myspray]!") - else if(user.transferItemToLoc(attacking_item, src)) - balloon_alert(user, "placed [attacking_item]") - return + return ITEM_INTERACT_BLOCKING - if(istype(attacking_item, /obj/item/lightreplacer)) + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + balloon_alert(user, "placed [tool]") + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/lightreplacer)) if(myreplacer) balloon_alert(user, "already has \a [myreplacer]!") - else if(user.transferItemToLoc(attacking_item, src)) - balloon_alert(user, "placed [attacking_item]") - return + return ITEM_INTERACT_BLOCKING - else if(istype(attacking_item, /obj/item/clothing/suit/caution)) + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + balloon_alert(user, "placed [tool]") + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/clothing/suit/caution)) if(held_signs.len >= max_signs) balloon_alert(user, "sign rack is full!") - else if(user.transferItemToLoc(attacking_item, src)) - balloon_alert(user, "placed [attacking_item]") - return + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + balloon_alert(user, "placed [tool]") + return ITEM_INTERACT_SUCCESS return ..() @@ -248,19 +262,15 @@ update_appearance(UPDATE_OVERLAYS) return ITEM_INTERACT_SUCCESS -/obj/structure/mop_bucket/janitorialcart/attackby_secondary(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/mop_bucket/janitorialcart/item_interaction_secondary(mob/living/user, obj/item/tool, list/modifiers) . = ..() - if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + if(ITEM_INTERACT_ANY_BLOCKER & .) + return . - if(istype(weapon, /obj/item/reagent_containers)) - update_appearance(UPDATE_OVERLAYS) - return SECONDARY_ATTACK_CONTINUE_CHAIN //so we can empty the cart via our afterattack without trying to put the item in the bag + if(!mybag?.atom_storage.attempt_insert(tool, user)) + return . - if(mybag?.attackby(weapon, user)) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - - return SECONDARY_ATTACK_CONTINUE_CHAIN + return ITEM_INTERACT_SUCCESS /obj/structure/mop_bucket/janitorialcart/attack_hand(mob/user, list/modifiers) . = ..() diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 2988c564754..6cbe466f474 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -51,19 +51,22 @@ default_unfasten_wrench(user, tool) return TRUE -/obj/structure/kitchenspike_frame/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/kitchenspike_frame/item_interaction(mob/living/user, obj/item/tool, list/modifiers) add_fingerprint(user) - if(!istype(attacking_item, /obj/item/stack/rods)) - return ..() - var/obj/item/stack/rods/used_rods = attacking_item - if(used_rods.get_amount() >= MEATSPIKE_IRONROD_REQUIREMENT) - used_rods.use(MEATSPIKE_IRONROD_REQUIREMENT) - balloon_alert(user, "meatspike built") - var/obj/structure/new_meatspike = new /obj/structure/kitchenspike(loc) - transfer_fingerprints_to(new_meatspike) - qdel(src) - return - balloon_alert(user, "[MEATSPIKE_IRONROD_REQUIREMENT] rods needed!") + if(!istype(tool, /obj/item/stack/rods)) + return NONE + + var/obj/item/stack/rods/used_rods = tool + if(used_rods.get_amount() < MEATSPIKE_IRONROD_REQUIREMENT) + balloon_alert(user, "[MEATSPIKE_IRONROD_REQUIREMENT] rods needed!") + return ITEM_INTERACT_BLOCKING + + used_rods.use(MEATSPIKE_IRONROD_REQUIREMENT) + var/obj/structure/new_meatspike = new /obj/structure/kitchenspike(loc) + new_meatspike.balloon_alert(user, "meatspike built") + transfer_fingerprints_to(new_meatspike) + qdel(src) + return ITEM_INTERACT_SUCCESS /obj/structure/kitchenspike name = "meat spike" diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 88423eb182c..5d72f1b39e2 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -388,16 +388,17 @@ use(user, going_up = FALSE) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/structure/ladder/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/ladder/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(user.combat_mode) + return NONE use(user) - return TRUE + return ITEM_INTERACT_SUCCESS -/obj/structure/ladder/attackby_secondary(obj/item/item, mob/user, list/modifiers, list/attack_modifiers) - . = ..() - if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) - return +/obj/structure/ladder/item_interaction_secondary(mob/living/user, obj/item/tool, list/modifiers) + if(user.combat_mode) + return NONE use(user, going_up = FALSE) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ITEM_INTERACT_SUCCESS /obj/structure/ladder/attack_robot(mob/living/silicon/robot/user) if(user.Adjacent(src)) diff --git a/code/game/objects/structures/maintenance.dm b/code/game/objects/structures/maintenance.dm index c6be3348e74..a23f3cd3c90 100644 --- a/code/game/objects/structures/maintenance.dm +++ b/code/game/objects/structures/maintenance.dm @@ -93,29 +93,35 @@ at the cost of risking a vicious bite.**/ return to_chat(user, span_warning("You find nothing of value...")) -/obj/structure/moisture_trap/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/moisture_trap/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(iscyborg(user) || isalien(user) || !CanReachInside(user)) - return ..() + return NONE + add_fingerprint(user) - if(is_reagent_container(I)) - if(istype(I, /obj/item/food/monkeycube)) - var/obj/item/food/monkeycube/cube = I + if(is_reagent_container(tool)) + if(istype(tool, /obj/item/food/monkeycube)) + var/obj/item/food/monkeycube/cube = tool cube.Expand() - return - var/obj/item/reagent_containers/reagent_container = I + return ITEM_INTERACT_SUCCESS + + var/obj/item/reagent_containers/reagent_container = tool if(reagent_container.is_open_container()) reagent_container.reagents.add_reagent(/datum/reagent/water, min(reagent_container.volume - reagent_container.reagents.total_volume, reagent_container.amount_per_transfer_from_this)) to_chat(user, span_notice("You fill [reagent_container] from [src].")) - return + return ITEM_INTERACT_SUCCESS + if(hidden_item) to_chat(user, span_warning("There is already something inside [src].")) - return - if(!user.transferItemToLoc(I, src)) - to_chat(user, span_warning("\The [I] is stuck to your hand, you cannot put it in [src]!")) - return - hidden_item = I - to_chat(user, span_notice("You hide [I] inside the basin.")) + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + to_chat(user, span_warning("\The [tool] is stuck to your hand, you cannot put it in [src]!")) + return ITEM_INTERACT_BLOCKING + + hidden_item = tool + to_chat(user, span_notice("You hide [tool] inside the basin.")) playsound(src,'sound/effects/splash.ogg', 55, TRUE) + return ITEM_INTERACT_SUCCESS #define ALTAR_INACTIVE 0 #define ALTAR_STAGEONE 1 @@ -138,11 +144,11 @@ at the cost of risking a vicious bite.**/ /// Stage of the pants making process var/status = ALTAR_INACTIVE -/obj/structure/destructible/cult/pants_altar/attackby(obj/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(attacking_item, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user) && status) - to_chat(user, span_notice("[src] is creating something, you can't move it!")) - return - return ..() +/obj/structure/destructible/cult/pants_altar/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/melee/cultblade/dagger) || !IS_CULTIST(user) || !status) + return NONE + to_chat(user, span_notice("[src] is creating something, you can't move it!")) + return ITEM_INTERACT_SUCCESS /obj/structure/destructible/cult/pants_altar/attack_hand(mob/living/user, list/modifiers) . = ..() diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 1a194dd0df3..1057b4771c8 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -138,13 +138,14 @@ icon_state = "[initial(icon_state)][door_opened ? "open":""]" return ..() -/obj/structure/mineral_door/attackby(obj/item/I, mob/living/user) - if(pickaxe_door(user, I)) - return - else if(!user.combat_mode) - return attack_hand(user) - else - return ..() +/obj/structure/mineral_door/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(pickaxe_door(user, tool)) + return ITEM_INTERACT_SUCCESS + + if(!user.combat_mode) + return attack_hand(user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING + + return NONE /obj/structure/mineral_door/set_anchored(anchorvalue) //called in default_unfasten_wrench() chain . = ..() @@ -281,10 +282,10 @@ /obj/structure/mineral_door/wood/crowbar_act(mob/living/user, obj/item/I) return crowbar_door(user, I) -/obj/structure/mineral_door/wood/attackby(obj/item/I, mob/living/user) - if(I.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) - fire_act(I.get_temperature()) - return +/obj/structure/mineral_door/wood/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(tool.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + fire_act(tool.get_temperature()) + return ITEM_INTERACT_SUCCESS return ..() @@ -317,18 +318,19 @@ /obj/structure/mineral_door/paperframe/crowbar_act(mob/living/user, obj/item/I) return crowbar_door(user, I) -/obj/structure/mineral_door/paperframe/attackby(obj/item/I, mob/living/user) - if(I.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) //BURN IT ALL DOWN JIM - fire_act(I.get_temperature()) - return +/obj/structure/mineral_door/paperframe/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(tool.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) //BURN IT ALL DOWN JIM + fire_act(tool.get_temperature()) + return ITEM_INTERACT_SUCCESS - if((!user.combat_mode) && istype(I, /obj/item/paper) && (atom_integrity < max_integrity)) + if(!user.combat_mode && istype(tool, /obj/item/paper) && (atom_integrity < max_integrity)) user.visible_message(span_notice("[user] starts to patch the holes in [src]."), span_notice("You start patching some of the holes in [src]!")) - if(do_after(user, 2 SECONDS, src)) - atom_integrity = min(atom_integrity+4,max_integrity) - qdel(I) - user.visible_message(span_notice("[user] patches some of the holes in [src]."), span_notice("You patch some of the holes in [src]!")) - return TRUE + if(!do_after(user, 2 SECONDS, src)) + return ITEM_INTERACT_BLOCKING + atom_integrity = min(atom_integrity+4,max_integrity) + qdel(tool) + user.visible_message(span_notice("[user] patches some of the holes in [src]."), span_notice("You patch some of the holes in [src]!")) + return ITEM_INTERACT_SUCCESS return ..() diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 3fb3ff29410..56692c15710 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -566,16 +566,18 @@ GLOBAL_LIST_EMPTY(crematoriums) to_chat(user, span_warning("That's not connected to anything!")) add_fingerprint(user) -/obj/structure/tray/attackby(obj/P, mob/user, list/modifiers, list/attack_modifiers) - if(!istype(P, /obj/item/riding_offhand)) - return ..() +/obj/structure/tray/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/riding_offhand)) + return NONE - var/obj/item/riding_offhand/riding_item = P + var/obj/item/riding_offhand/riding_item = tool var/mob/living/carried_mob = riding_item.rider if(carried_mob == user) //Piggyback user. - return + return ITEM_INTERACT_BLOCKING + user.unbuckle_mob(carried_mob) mouse_drop_receive(carried_mob, user) + return ITEM_INTERACT_SUCCESS /obj/structure/tray/mouse_drop_receive(atom/movable/O as mob|obj, mob/user, params) if(!ismovable(O) || O.anchored || O.loc == user) diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index ed7ef50f383..a8af8bea6c3 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -39,21 +39,26 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/noticeboard, 32) find_and_mount_on_atom() //attaching papers!! -/obj/structure/noticeboard/attackby(obj/item/O, mob/user, list/modifiers, list/attack_modifiers) - if(istype(O, /obj/item/paper) || istype(O, /obj/item/photo)) - if(!allowed(user)) - to_chat(user, span_warning("You are not authorized to add notices!")) - return - if(notices < MAX_NOTICES) - if(!user.transferItemToLoc(O, src)) - return - notices++ - update_appearance(UPDATE_ICON) - to_chat(user, span_notice("You pin the [O] to the noticeboard.")) - else - to_chat(user, span_warning("The notice board is full!")) - else - return ..() +/obj/structure/noticeboard/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/paper) && !istype(tool, /obj/item/photo)) + return NONE + + if(!allowed(user)) + to_chat(user, span_warning("You are not authorized to add notices!")) + return ITEM_INTERACT_BLOCKING + + if(notices >= MAX_NOTICES) + to_chat(user, span_warning("The notice board is full!")) + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + notices++ + update_appearance(UPDATE_ICON) + to_chat(user, span_notice("You pin the [tool] to the noticeboard.")) + return ITEM_INTERACT_SUCCESS + /obj/structure/noticeboard/ui_state(mob/user) return GLOB.physical_state diff --git a/code/game/objects/structures/ore_containers.dm b/code/game/objects/structures/ore_containers.dm index ba8e59cc78a..047799a2276 100644 --- a/code/game/objects/structures/ore_containers.dm +++ b/code/game/objects/structures/ore_containers.dm @@ -1,11 +1,11 @@ ///structure to contain ores /obj/structure/ore_container -/obj/structure/ore_container/attackby(obj/item/ore, mob/living/carbon/human/user, list/modifiers, list/attack_modifiers) - if(istype(ore, /obj/item/stack/ore) && !user.combat_mode) - ore.forceMove(src) - return - return ..() +/obj/structure/ore_container/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/stack/ore) || user.combat_mode) + return NONE + tool.forceMove(src) + return ITEM_INTERACT_SUCCESS /obj/structure/ore_container/Entered(atom/movable/mover) . = ..() diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index 7fa9a6ccb18..820057b842b 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -82,34 +82,40 @@ else . += span_notice("The railing is unbolted from the floor and can be deconstructed with wirecutters.") -/obj/structure/railing/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers) - ..() +/obj/structure/railing/item_interaction(mob/living/user, obj/item/tool, list/modifiers) add_fingerprint(user) + return ..() - if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode) - if(atom_integrity < max_integrity) - if(!I.tool_start_check(user, amount=1)) - return +/obj/structure/railing/welder_act(mob/living/user, obj/item/tool) + if(user.combat_mode) + return NONE - to_chat(user, span_notice("You begin repairing [src]...")) - if(I.use_tool(src, user, 40, volume=50)) - atom_integrity = max_integrity - to_chat(user, span_notice("You repair [src].")) - else - to_chat(user, span_warning("[src] is already in good condition!")) - return + add_fingerprint(user) + if(atom_integrity == max_integrity) + to_chat(user, span_warning("[src] is already in good condition!")) + return ITEM_INTERACT_BLOCKING + + if(!tool.tool_start_check(user, amount=1)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You begin repairing [src]...")) + if(!tool.use_tool(src, user, 40, volume=50)) + return ITEM_INTERACT_BLOCKING + + atom_integrity = max_integrity + to_chat(user, span_notice("You repair [src].")) + return ITEM_INTERACT_SUCCESS /obj/structure/railing/wirecutter_act(mob/living/user, obj/item/I) - . = ..() if(resistance_flags & INDESTRUCTIBLE) to_chat(user, span_warning("You try to cut apart the railing, but it's too hard!")) I.play_tool_sound(src, 100) - return TRUE + return ITEM_INTERACT_BLOCKING to_chat(user, span_warning("You cut apart the railing.")) I.play_tool_sound(src, 100) deconstruct() - return TRUE + return ITEM_INTERACT_SUCCESS /obj/structure/railing/atom_deconstruct(disassembled) var/rods_to_make = istype(src,/obj/structure/railing/corner) ? 1 : 2 diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index 082a140d699..9cb9690c20c 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -131,34 +131,42 @@ return ITEM_INTERACT_SUCCESS -/obj/structure/reflector/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/reflector/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(admin) - return + return ITEM_INTERACT_BLOCKING //Finishing the frame - else if(istype(W, /obj/item/stack/sheet)) - if(finished) - return - var/obj/item/stack/sheet/S = W - if(istype(S, /obj/item/stack/sheet/glass)) - if(S.use(5)) - new /obj/structure/reflector/single(drop_location()) - qdel(src) - else - to_chat(user, span_warning("You need five sheets of glass to create a reflector!")) - return - if(istype(S, /obj/item/stack/sheet/rglass)) - if(S.use(10)) - new /obj/structure/reflector/double(drop_location()) - qdel(src) - else - to_chat(user, span_warning("You need ten sheets of reinforced glass to create a double reflector!")) - return - if(istype(S, /obj/item/stack/sheet/mineral/diamond)) - if(S.use(1)) - new /obj/structure/reflector/box(drop_location()) - qdel(src) - else - return ..() + if(!istype(tool, /obj/item/stack/sheet)) + return NONE + + if(finished) + return ITEM_INTERACT_BLOCKING + + var/obj/item/stack/sheet/using_stack = tool + if(istype(using_stack, /obj/item/stack/sheet/glass)) + if(!using_stack.use(5)) + to_chat(user, span_warning("You need five sheets of glass to create a reflector!")) + return ITEM_INTERACT_BLOCKING + + new /obj/structure/reflector/single(drop_location()) + qdel(src) + return ITEM_INTERACT_SUCCESS + + if(istype(using_stack, /obj/item/stack/sheet/rglass)) + if(!using_stack.use(10)) + to_chat(user, span_warning("You need ten sheets of reinforced glass to create a double reflector!")) + return ITEM_INTERACT_BLOCKING + + new /obj/structure/reflector/double(drop_location()) + qdel(src) + return ITEM_INTERACT_SUCCESS + + if(istype(using_stack, /obj/item/stack/sheet/mineral/diamond)) + if(!using_stack.use(1)) + return ITEM_INTERACT_BLOCKING + + new /obj/structure/reflector/box(drop_location()) + qdel(src) + return ITEM_INTERACT_SUCCESS /obj/structure/reflector/proc/rotate(mob/user) if (!can_rotate || admin) diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 0822d1db77c..b6141a44c7b 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -118,24 +118,27 @@ FLOOR SAFES balloon_alert(user, "lock set!") return ITEM_INTERACT_SUCCESS -/obj/structure/safe/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - if(open) - . = TRUE //no afterattack - if(attacking_item.w_class + space <= maxspace) - if(!user.transferItemToLoc(attacking_item, src)) - to_chat(user, span_warning("\The [attacking_item] is stuck to your hand, you cannot put it in the safe!")) - return - space += attacking_item.w_class - to_chat(user, span_notice("You put [attacking_item] in [src].")) - else - to_chat(user, span_warning("[attacking_item] won't fit in [src].")) - else - if(istype(attacking_item, /obj/item/clothing/neck/stethoscope)) - attack_hand(user) - return - else - to_chat(user, span_warning("You can't put [attacking_item] into the safe while it is closed!")) - return +/obj/structure/safe/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!open) + if(!istype(tool, /obj/item/clothing/neck/stethoscope)) + to_chat(user, span_warning("You can't put [tool] into the safe while it is closed!")) + return ITEM_INTERACT_BLOCKING + + attack_hand(user) + return ITEM_INTERACT_SUCCESS + + if(tool.w_class + space > maxspace) + to_chat(user, span_warning("[tool] won't fit in [src].")) + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + to_chat(user, span_warning("\The [tool] is stuck to your hand, you cannot put it in the safe!")) + return ITEM_INTERACT_BLOCKING + + space += tool.w_class + to_chat(user, span_notice("You put [tool] in [src].")) + return ITEM_INTERACT_SUCCESS + /obj/structure/safe/blob_act(obj/structure/blob/B) return diff --git a/code/game/objects/structures/shower.dm b/code/game/objects/structures/shower.dm index b148dacda1f..ef660c3e0aa 100644 --- a/code/game/objects/structures/shower.dm +++ b/code/game/objects/structures/shower.dm @@ -138,18 +138,19 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) begin_processing() return TRUE -/obj/machinery/shower/attackby(obj/item/tool, mob/user, list/modifiers, list/attack_modifiers) - if(istype(tool, /obj/item/stock_parts/water_recycler)) - if(has_water_reclaimer) - to_chat(user, span_warning("There is already has a water recycler installed.")) - return +/obj/machinery/shower/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/stock_parts/water_recycler)) + return NONE - playsound(src, 'sound/machines/click.ogg', 20, TRUE) - qdel(tool) - has_water_reclaimer = TRUE - begin_processing() + if(has_water_reclaimer) + to_chat(user, span_warning("There is already has a water recycler installed.")) + return ITEM_INTERACT_BLOCKING - return ..() + playsound(src, 'sound/machines/click.ogg', 20, TRUE) + qdel(tool) + has_water_reclaimer = TRUE + begin_processing() + return ITEM_INTERACT_SUCCESS /obj/machinery/shower/multitool_act(mob/living/user, obj/item/tool) . = ..() @@ -390,14 +391,15 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) . = ..() AddElement(/datum/element/simple_rotation) -/obj/structure/showerframe/attackby(obj/item/tool, mob/living/user, list/modifiers, list/attack_modifiers) - if(istype(tool, /obj/item/stock_parts/water_recycler)) - qdel(tool) - var/obj/machinery/shower/shower = new(loc, REVERSE_DIR(dir), TRUE) - qdel(src) - playsound(shower, 'sound/machines/click.ogg', 20, TRUE) - return - return ..() +/obj/structure/showerframe/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/stock_parts/water_recycler)) + return NONE + + qdel(tool) + var/obj/machinery/shower/shower = new(loc, REVERSE_DIR(dir), TRUE) + qdel(src) + playsound(shower, 'sound/machines/click.ogg', 20, TRUE) + return ITEM_INTERACT_SUCCESS /obj/structure/showerframe/wrench_act(mob/living/user, obj/item/tool) . = ..() diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm index bf8d713eb14..f705d2fc5ce 100644 --- a/code/game/objects/structures/spawner.dm +++ b/code/game/objects/structures/spawner.dm @@ -39,13 +39,11 @@ else . += span_notice("It looks like you could probably scan and tag it with a [scanner_descriptor].") -/obj/structure/spawner/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers) - . = ..() - if(.) - return TRUE - if(scanner_taggable && is_type_in_list(item, scanner_types)) +/obj/structure/spawner/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!scanner_taggable || !is_type_in_list(tool, scanner_types)) gps_tag(user) - return TRUE + return ITEM_INTERACT_SUCCESS + return NONE /// Tag the spawner, prefixing its GPS entry with an identifier - or giving it one, if nonexistent. /obj/structure/spawner/proc/gps_tag(mob/user) diff --git a/code/game/objects/structures/stairs.dm b/code/game/objects/structures/stairs.dm index 0f037fec4d5..416984dd660 100644 --- a/code/game/objects/structures/stairs.dm +++ b/code/game/objects/structures/stairs.dm @@ -421,39 +421,50 @@ /obj/structure/stairs_frame/atom_deconstruct(disassembled = TRUE) new frame_stack(get_turf(src), frame_stack_amount) -/obj/structure/stairs_frame/attackby(obj/item/attacked_by, mob/user, list/modifiers, list/attack_modifiers) - if(!isstack(attacked_by)) - return ..() +/obj/structure/stairs_frame/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!isstack(tool)) + return NONE if(!anchored) - user.balloon_alert(user, "secure frame first") - return TRUE - var/obj/item/stack/material = attacked_by + user.balloon_alert(user, "secure the frame first!") + return ITEM_INTERACT_BLOCKING + + var/obj/item/stack/material = tool if(material.stairs_type) if(material.get_amount() < 10) to_chat(user, span_warning("You need ten [material.name] sheets to do this!")) - return + return ITEM_INTERACT_BLOCKING + if(locate(/obj/structure/stairs) in loc) to_chat(user, span_warning("There's already stairs built here!")) - return + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You start adding [material] to [src]...")) if(!do_after(user, 10 SECONDS, target = src) || !material.use(10) || (locate(/obj/structure/table) in loc)) - return + return ITEM_INTERACT_BLOCKING + make_new_stairs(material.stairs_type) - else if(istype(material, /obj/item/stack/sheet)) + return ITEM_INTERACT_SUCCESS + + if(istype(material, /obj/item/stack/sheet)) if(material.get_amount() < 10) to_chat(user, span_warning("You need ten sheets to do this!")) - return + return ITEM_INTERACT_BLOCKING + if(locate(/obj/structure/stairs) in loc) to_chat(user, span_warning("There's already stairs built here!")) - return + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You start adding [material] to [src]...")) if(!do_after(user, 10 SECONDS, target = src) || !material.use(10) || (locate(/obj/structure/table) in loc)) - return + return ITEM_INTERACT_BLOCKING + var/list/material_list = list() if(material.material_type) material_list[material.material_type] = SHEET_MATERIAL_AMOUNT * 10 make_new_stairs(/obj/structure/stairs/material, material_list) - return TRUE + return ITEM_INTERACT_SUCCESS + + return NONE /obj/structure/stairs_frame/proc/make_new_stairs(stairs_type, custom_materials) var/obj/structure/stairs/new_stairs = new stairs_type(loc) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index aa288c06bf7..f915c0d8916 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -59,31 +59,29 @@ default_unfasten_wrench(user, tool) return ITEM_INTERACT_SUCCESS -/obj/structure/tank_dispenser/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers) - var/full - if(istype(I, /obj/item/tank/internals/plasma)) - if(plasmatanks < TANK_DISPENSER_CAPACITY) - plasmatanks++ - else - full = TRUE - else if(istype(I, /obj/item/tank/internals/oxygen)) - if(oxygentanks < TANK_DISPENSER_CAPACITY) - oxygentanks++ - else - full = TRUE - else if(!user.combat_mode || (I.item_flags & NOBLUDGEON)) - balloon_alert(user, "can't insert!") - return +/obj/structure/tank_dispenser/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/tank/internals/plasma)) + if(plasmatanks == TANK_DISPENSER_CAPACITY) + balloon_alert(user, "it is full!") + return ITEM_INTERACT_BLOCKING + plasmatanks++ + else if(istype(tool, /obj/item/tank/internals/oxygen)) + if(oxygentanks == TANK_DISPENSER_CAPACITY) + balloon_alert(user, "it is full!") + return ITEM_INTERACT_BLOCKING + oxygentanks++ else - return ..() - if(full) - balloon_alert(user, "it is full!") - return + if(!user.combat_mode || (tool.item_flags & NOBLUDGEON)) + balloon_alert(user, "can't insert!") + return ITEM_INTERACT_BLOCKING + return NONE + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING - if(!user.transferItemToLoc(I, src)) - return balloon_alert(user, "tank inserted") update_appearance() + return ITEM_INTERACT_SUCCESS /obj/structure/tank_dispenser/atom_deconstruct(disassembled = TRUE) for(var/X in src) diff --git a/code/game/objects/structures/tank_holder.dm b/code/game/objects/structures/tank_holder.dm index 3d0b5e18b75..ce1f428cfd9 100644 --- a/code/game/objects/structures/tank_holder.dm +++ b/code/game/objects/structures/tank_holder.dm @@ -45,17 +45,27 @@ . += span_notice("It is empty.") . += span_notice("It is held together by some screws.") -/obj/structure/tank_holder/attackby(obj/item/W, mob/living/user, list/modifiers, list/attack_modifiers) +/obj/structure/tank_holder/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(user.combat_mode) - return ..() - if(W.tool_behaviour == TOOL_WRENCH) - to_chat(user, span_notice("You begin to [anchored ? "unwrench" : "wrench"] [src].")) - if(W.use_tool(src, user, 20, volume=50)) - to_chat(user, span_notice("You successfully [anchored ? "unwrench" : "wrench"] [src].")) - set_anchored(!anchored) - else if(!SEND_SIGNAL(W, COMSIG_CONTAINER_TRY_ATTACH, src, user)) - to_chat(user, span_warning("[W] does not fit in [src].")) - return + return NONE + + if(!SEND_SIGNAL(tool, COMSIG_CONTAINER_TRY_ATTACH, src, user)) + to_chat(user, span_warning("[tool] does not fit in [src].")) + return ITEM_INTERACT_BLOCKING + + return ITEM_INTERACT_SUCCESS + +/obj/structure/tank_holder/wrench_act(mob/living/user, obj/item/tool) + if(user.combat_mode) + return NONE + + to_chat(user, span_notice("You begin to [anchored ? "unwrench" : "wrench"] [src].")) + if(!tool.use_tool(src, user, 20, volume=50)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You successfully [anchored ? "unwrench" : "wrench"] [src].")) + set_anchored(!anchored) + return ITEM_INTERACT_SUCCESS /obj/structure/tank_holder/screwdriver_act(mob/living/user, obj/item/I) if(..()) diff --git a/code/game/objects/structures/toiletbong.dm b/code/game/objects/structures/toiletbong.dm index 4d8eed5386d..1182c3d8fd9 100644 --- a/code/game/objects/structures/toiletbong.dm +++ b/code/game/objects/structures/toiletbong.dm @@ -110,8 +110,3 @@ if (emag_card) to_chat(user, span_boldwarning("The [emag_card] falls into the toilet. You fish it back out. Looks like you broke the toilet.")) return TRUE - -/obj/structure/toiletbong/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - if(istype(attacking_item, /obj/item/card/emag)) - return - return ..() diff --git a/code/game/objects/structures/training_machine.dm b/code/game/objects/structures/training_machine.dm index f6c12c155f3..c84f630fe51 100644 --- a/code/game/objects/structures/training_machine.dm +++ b/code/game/objects/structures/training_machine.dm @@ -108,17 +108,21 @@ * Meant for attaching an item to the machine, should only be a training toolbox or target. If emagged, the * machine will gain an auto-attached syndicate toolbox, so in that case we shouldn't be able to swap it out */ -/obj/structure/training_machine/attackby(obj/item/target, mob/living/user) +/obj/structure/training_machine/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if (user.combat_mode) - return ..() - if (!istype(target, /obj/item/training_toolbox) && !istype(target, /obj/item/target)) - return ..() + return NONE + + if (!istype(tool, /obj/item/training_toolbox) && !istype(tool, /obj/item/target)) + return NONE + if (obj_flags & EMAGGED) to_chat(user, span_warning("The toolbox is somehow stuck on! It won't budge!")) - return - attach_item(target) + return ITEM_INTERACT_BLOCKING + + attach_item(tool) to_chat(user, span_notice("You attach \the [attached_item] to the training device.")) playsound(src, SFX_RUSTLE, 50, TRUE) + return ITEM_INTERACT_SUCCESS /** * Attach an item to the machine diff --git a/code/game/objects/structures/votingbox.dm b/code/game/objects/structures/votingbox.dm index 8ab34de74ba..5451e8d6f73 100644 --- a/code/game/objects/structures/votingbox.dm +++ b/code/game/objects/structures/votingbox.dm @@ -19,18 +19,22 @@ var/list/voted //List of ID's that already voted. COOLDOWN_DECLARE(vote_print_cooldown) -/obj/structure/votebox/attackby(obj/item/I, mob/living/user, list/modifiers, list/attack_modifiers) - if(istype(I,/obj/item/card/id)) - if(!owner) - register_owner(I,user) - return - if(istype(I,/obj/item/paper)) - if(voting_active) - apply_vote(I,user) - else +/obj/structure/votebox/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/card/id)) + if(owner) + return ITEM_INTERACT_BLOCKING + + register_owner(tool ,user) + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/paper)) + if(!voting_active) to_chat(user,span_warning("[src] is in maintenance mode. Voting is not possible at the moment.")) - return - return ..() + return ITEM_INTERACT_BLOCKING + apply_vote(tool ,user) + return ITEM_INTERACT_SUCCESS + + return NONE /obj/structure/votebox/interact(mob/user) ..() diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index a8aaa2620af..ee827efaad4 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -1,3 +1,5 @@ +#define WINDOOR_LEFT "l" +#define WINDOOR_RIGHT "r" /obj/structure/windoor_assembly icon = 'icons/obj/doors/windoor.dmi' @@ -20,20 +22,21 @@ //Vars to help with the icon's name ///Does the windoor open to the left or right? - var/facing = "l" + var/facing = WINDOOR_LEFT ///Whether or not this creates a secure windoor var/secure = FALSE /** - * Windoor (window door) assembly -Nodrak - * Step 1: Create a windoor out of rglass - * Step 2: Add r-glass to the assembly to make a secure windoor (Optional) - * Step 3: Rotate or Flip the assembly to face and open the way you want - * Step 4: Wrench the assembly in place - * Step 5: Add cables to the assembly - * Step 6: Set access for the door. - * Step 7: Crowbar the door to complete + * Windoor (window door) assembly -Nodrak ----------- with comments clarifying what's actually happening, and how we know what step we're on + * Step 1: Create a windoor out of rglass -no variables modified. Destroy via welder + * Step 2: Add r-glass to the assembly to make a secure windoor (Optional) -tracked by secure, can be done anytime before cables_added is TRUE. Cannot be undone + * Step 3: Rotate or Flip the assembly to face and open the way you want -tracked by facing, can be done any time before anchoring via wrench right click + * Step 4: Wrench the assembly in place -tracked by anchored, no requisites, undone with wrench as well if cabling not yet inserted + * Step 5: Add cables to the assembly -tracked by cables_added, requires being anchored, undoable with wirecutters with no requisites until full completion + * Step 6: Set access for the door. -tracked by electronics, requires cabling to install electronics, undoable with screwdriver requiring cabling to remain + * Step 7: Crowbar the door to complete -requires cabling & electronics, not undoable. obviously. */ - var/state = "01" + + var/cables_added = FALSE /obj/structure/windoor_assembly/Initialize(mapload, set_dir) @@ -60,7 +63,7 @@ move_update_air(T) /obj/structure/windoor_assembly/update_icon_state() - icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]" + icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[cables_added ? "02" : "01"]" return ..() /obj/structure/windoor_assembly/CanAllowThrough(atom/movable/mover, border_dir) @@ -98,199 +101,262 @@ leaving.Bump(src) return COMPONENT_ATOM_BLOCK_EXIT -/obj/structure/windoor_assembly/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/windoor_assembly/item_interaction(mob/living/user, obj/item/tool, list/modifiers) //I really should have spread this out across more states but thin little windoors are hard to sprite. add_fingerprint(user) - switch(state) - if("01") - if(W.tool_behaviour == TOOL_WELDER && !anchored) - if(!W.tool_start_check(user, amount=1)) - return + if(!cables_added) + //Adding plasteel makes the assembly a secure windoor assembly. Step 2 (optional) complete. + if(istype(tool, /obj/item/stack/sheet/plasteel) && !secure) + var/obj/item/stack/sheet/plasteel/reinforcement = tool + if(reinforcement.get_amount() < 2) + to_chat(user, span_warning("You need more plasteel to do this!")) + return ITEM_INTERACT_BLOCKING - user.visible_message(span_notice("[user] disassembles the windoor assembly."), - span_notice("You start to disassemble the windoor assembly...")) + to_chat(user, span_notice("You start to reinforce the windoor with plasteel...")) - if(W.use_tool(src, user, 40, volume=50)) - to_chat(user, span_notice("You disassemble the windoor assembly.")) - var/obj/item/stack/sheet/rglass/RG = new (get_turf(src), 5) - if (!QDELETED(RG)) - RG.add_fingerprint(user) - if(secure) - var/obj/item/stack/rods/R = new (get_turf(src), 4) - if (!QDELETED(R)) - R.add_fingerprint(user) - qdel(src) - return + if(!do_after(user, 4 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING - //Wrenching an unsecure assembly anchors it in place. Step 4 complete - if(W.tool_behaviour == TOOL_WRENCH && !anchored) - for(var/obj/machinery/door/window/WD in loc) - if(WD.dir == dir) - to_chat(user, span_warning("There is already a windoor in that location!")) - return - user.visible_message(span_notice("[user] secures the windoor assembly to the floor."), - span_notice("You start to secure the windoor assembly to the floor...")) + if(!src || secure || reinforcement.get_amount() < 2) + return ITEM_INTERACT_BLOCKING - if(W.use_tool(src, user, 40, volume=100)) - if(anchored) - return - for(var/obj/machinery/door/window/WD in loc) - if(WD.dir == dir) - to_chat(user, span_warning("There is already a windoor in that location!")) - return - to_chat(user, span_notice("You secure the windoor assembly.")) - set_anchored(TRUE) - if(secure) - name = "secure anchored windoor assembly" - else - name = "anchored windoor assembly" - - //Unwrenching an unsecure assembly un-anchors it. Step 4 undone - else if(W.tool_behaviour == TOOL_WRENCH && anchored) - user.visible_message(span_notice("[user] unsecures the windoor assembly to the floor."), - span_notice("You start to unsecure the windoor assembly to the floor...")) - - if(W.use_tool(src, user, 40, volume=100)) - if(!anchored) - return - to_chat(user, span_notice("You unsecure the windoor assembly.")) - set_anchored(FALSE) - if(secure) - name = "secure windoor assembly" - else - name = "windoor assembly" - - //Adding plasteel makes the assembly a secure windoor assembly. Step 2 (optional) complete. - else if(istype(W, /obj/item/stack/sheet/plasteel) && !secure) - var/obj/item/stack/sheet/plasteel/P = W - if(P.get_amount() < 2) - to_chat(user, span_warning("You need more plasteel to do this!")) - return - to_chat(user, span_notice("You start to reinforce the windoor with plasteel...")) - - if(do_after(user,40, target = src)) - if(!src || secure || P.get_amount() < 2) - return - - P.use(2) - to_chat(user, span_notice("You reinforce the windoor.")) - secure = TRUE - if(anchored) - name = "secure anchored windoor assembly" - else - name = "secure windoor assembly" - - //Adding cable to the assembly. Step 5 complete. - else if(istype(W, /obj/item/stack/cable_coil) && anchored) - user.visible_message(span_notice("[user] wires the windoor assembly."), span_notice("You start to wire the windoor assembly...")) - - if(do_after(user, 4 SECONDS, target = src)) - if(!src || !anchored || src.state != "01") - return - var/obj/item/stack/cable_coil/CC = W - if(!CC.use(1)) - to_chat(user, span_warning("You need more cable to do this!")) - return - to_chat(user, span_notice("You wire the windoor.")) - state = "02" - if(secure) - name = "secure wired windoor assembly" - else - name = "wired windoor assembly" + reinforcement.use(2) + to_chat(user, span_notice("You reinforce the windoor.")) + secure = TRUE + if(anchored) + name = "secure anchored windoor assembly" else - return ..() + name = "secure windoor assembly" + update_appearance() + return ITEM_INTERACT_SUCCESS - if("02") + //Adding cable to the assembly. Step 5 complete. + if(istype(tool, /obj/item/stack/cable_coil) && anchored) + user.visible_message(span_notice("[user] wires the windoor assembly."), span_notice("You start to wire the windoor assembly...")) - //Removing wire from the assembly. Step 5 undone. - if(W.tool_behaviour == TOOL_WIRECUTTER) - user.visible_message(span_notice("[user] cuts the wires from the airlock assembly."), span_notice("You start to cut the wires from airlock assembly...")) + if(!do_after(user, 4 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING - if(W.use_tool(src, user, 40, volume=100)) - if(state != "02") - return + if(!anchored || cables_added) + return ITEM_INTERACT_BLOCKING - to_chat(user, span_notice("You cut the windoor wires.")) - new/obj/item/stack/cable_coil(get_turf(user), 1) - state = "01" - if(secure) - name = "secure anchored windoor assembly" - else - name = "anchored windoor assembly" - - //Adding airlock electronics for access. Step 6 complete. - else if(istype(W, /obj/item/electronics/airlock)) - - W.play_tool_sound(src, 100) - user.visible_message(span_notice("[user] installs the electronics into the airlock assembly."), - span_notice("You start to install electronics into the airlock assembly...")) - - if(do_after(user, 4 SECONDS, target = src)) - - if(!user.transferItemToLoc(W, src)) - return - if(!src || electronics) - W.forceMove(drop_location()) - return - to_chat(user, span_notice("You install the airlock electronics.")) - name = "near finished windoor assembly" - electronics = W - - //Screwdriver to remove airlock electronics. Step 6 undone. - else if(W.tool_behaviour == TOOL_SCREWDRIVER) - if(!electronics) - return - - user.visible_message(span_notice("[user] removes the electronics from the airlock assembly."), - span_notice("You start to uninstall electronics from the airlock assembly...")) - - if(W.use_tool(src, user, 40, volume=100) && electronics) - to_chat(user, span_notice("You remove the airlock electronics.")) - name = "wired windoor assembly" - var/obj/item/electronics/airlock/ae - ae = electronics - electronics = null - ae.forceMove(drop_location()) - - //Crowbar to complete the assembly, Step 7 complete. - else if(W.tool_behaviour == TOOL_CROWBAR) - if(!electronics) - to_chat(usr, span_warning("The assembly is missing electronics!")) - return - user.visible_message(span_notice("[user] pries the windoor into the frame."), - span_notice("You start prying the windoor into the frame...")) - - if(W.use_tool(src, user, 40, volume=100) && electronics) - set_density(TRUE) //Shouldn't matter but just incase - to_chat(user, span_notice("You finish the windoor.")) - finish_door() + var/obj/item/stack/cable_coil/wiring = tool + if(!wiring.use(1)) + to_chat(user, span_warning("You need more cable to do this!")) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You wire the windoor.")) + cables_added = TRUE + if(secure) + name = "secure wired windoor assembly" else - return ..() + name = "wired windoor assembly" + update_appearance() + return ITEM_INTERACT_SUCCESS + + return NONE + + //cables_added TRUE beyond this point + + //Adding airlock electronics for access. Step 6 complete. + if(istype(tool, /obj/item/electronics/airlock)) + + tool.play_tool_sound(src, 100) + user.visible_message(span_notice("[user] installs the electronics into the airlock assembly."), + span_notice("You start to install electronics into the airlock assembly...")) + + if(!do_after(user, 4 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + + if(!src || electronics) + tool.forceMove(drop_location()) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You install the airlock electronics.")) + name = "near finished windoor assembly" + electronics = tool + return ITEM_INTERACT_SUCCESS + + return NONE + +//dissasemble entirely unworked assembly +/obj/structure/windoor_assembly/welder_act(mob/living/user, obj/item/tool) + if(cables_added) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(!anchored) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(!tool.tool_start_check(user, amount=1)) + return ITEM_INTERACT_BLOCKING + + user.visible_message(span_notice("[user] disassembles the windoor assembly."), + span_notice("You start to disassemble the windoor assembly...")) + + if(!tool.use_tool(src, user, 4 SECONDS, volume = 50)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You disassemble the windoor assembly.")) + var/obj/item/stack/sheet/rglass/dropped_glass = new (get_turf(src), 5) + if(!QDELETED(dropped_glass)) + dropped_glass.add_fingerprint(user) + if(secure) + var/obj/item/stack/rods/dropped_rods = new (get_turf(src), 4) + if(!QDELETED(dropped_rods)) + dropped_rods.add_fingerprint(user) + qdel(src) + return ITEM_INTERACT_SUCCESS + +//secure or unsecure unworked assembly +/obj/structure/windoor_assembly/wrench_act(mob/living/user, obj/item/tool) + if(cables_added) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(!anchored) + for(var/obj/machinery/door/window/competitor in loc) + if(competitor.dir == dir) + to_chat(user, span_warning("There is already a windoor in that location!")) + return ITEM_INTERACT_BLOCKING + + user.visible_message(span_notice("[user] secures the windoor assembly to the floor."), + span_notice("You start to secure the windoor assembly to the floor...")) + if(!tool.use_tool(src, user, 4 SECONDS, volume=100)) + return ITEM_INTERACT_BLOCKING + + if(anchored) + return ITEM_INTERACT_BLOCKING + + for(var/obj/machinery/door/window/competitor in loc) + if(competitor.dir == dir) + to_chat(user, span_warning("There is already a windoor in that location!")) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You secure the windoor assembly.")) + set_anchored(TRUE) + if(secure) + name = "secure anchored windoor assembly" + else + name = "anchored windoor assembly" + return ITEM_INTERACT_SUCCESS + + //Unwrenching an unsecure assembly un-anchors it. Step 4 undone + user.visible_message(span_notice("[user] unsecures the windoor assembly to the floor."), + span_notice("You start to unsecure the windoor assembly to the floor...")) + + if(!tool.use_tool(src, user, 4 SECONDS, volume=100)) + return ITEM_INTERACT_BLOCKING + if(!anchored) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You unsecure the windoor assembly.")) + set_anchored(FALSE) + if(secure) + name = "secure windoor assembly" + else + name = "windoor assembly" + return ITEM_INTERACT_SUCCESS + +//Flips the windoor assembly, determines whether the door opens to the left or the right +/obj/structure/windoor_assembly/wrench_act_secondary(mob/living/user, obj/item/tool) + if(anchored) + return NONE + if(facing == WINDOOR_LEFT) + to_chat(usr, span_notice("The windoor will now slide to the right.")) + facing = WINDOOR_RIGHT + else + facing = WINDOOR_LEFT + to_chat(usr, span_notice("The windoor will now slide to the left.")) - //Update to reflect changes(if applicable) update_appearance() + return ITEM_INTERACT_SUCCESS + +//remove cabling +/obj/structure/windoor_assembly/wirecutter_act(mob/living/user, obj/item/tool) + if(!cables_added) + return ITEM_INTERACT_SKIP_TO_ATTACK + + user.visible_message(span_notice("[user] cuts the wires from the airlock assembly."), \ + span_notice("You start to cut the wires from airlock assembly...")) + if(!tool.use_tool(src, user, 4 SECONDS, volume=100)) + return ITEM_INTERACT_BLOCKING + + if(!cables_added) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You cut the windoor wires.")) + new/obj/item/stack/cable_coil(get_turf(user), 1) + cables_added = FALSE + if(secure) + name = "secure anchored windoor assembly" + else + name = "anchored windoor assembly" + update_appearance() + return ITEM_INTERACT_SUCCESS + +//remove airlock electronics +/obj/structure/windoor_assembly/screwdriver_act(mob/living/user, obj/item/tool) + if(!cables_added) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(!electronics) + return ITEM_INTERACT_SKIP_TO_ATTACK + + user.visible_message(span_notice("[user] removes the electronics from the airlock assembly."), + span_notice("You start to uninstall electronics from the airlock assembly...")) + + if(!tool.use_tool(src, user, 4 SECONDS, volume=100) && electronics) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You remove the airlock electronics.")) + name = "wired windoor assembly" + var/obj/item/electronics/airlock/scrap + scrap = electronics + electronics = null + scrap.forceMove(drop_location()) + return ITEM_INTERACT_SUCCESS + +//finishes door +/obj/structure/windoor_assembly/crowbar_act(mob/living/user, obj/item/tool) + if(!cables_added) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if(!electronics) + to_chat(usr, span_warning("The assembly is missing electronics!")) + return ITEM_INTERACT_BLOCKING + + user.visible_message(span_notice("[user] pries the windoor into the frame."), + span_notice("You start prying the windoor into the frame...")) + + if(!tool.use_tool(src, user, 4 SECONDS, volume=100) || !electronics) + return ITEM_INTERACT_BLOCKING + set_density(TRUE) //Shouldn't matter but just incase <-- in case what? + to_chat(user, span_notice("You finish the windoor.")) + finish_door() + return ITEM_INTERACT_SUCCESS /obj/structure/windoor_assembly/examine(mob/user) . = ..() if(!anchored) . += span_notice("\The [src] can be [span_boldnotice("wrenched")] down.") . += span_notice("\The [src] could also be [span_boldnotice("cut apart")] with a [span_boldnotice("welder")].") - return - switch(state) - if("01") - . += span_notice("\The [src] needs [span_boldnotice("wiring")], or could be [span_boldnotice("un-wrenched")] from the floor.") - if("02") - if(!electronics) - . += span_notice("\The [src] needs [span_boldnotice("airlock electronics")] to continue installation, or [span_boldnotice("wirecutters")] to take apart.") - else - . += span_notice("\The [src] is ready to be [span_boldnotice("levered")] into place with a [span_boldnotice("crowbar")].") + return . + + if(!cables_added) + . += span_notice("\The [src] needs [span_boldnotice("wiring")], or could be [span_boldnotice("un-wrenched")] from the floor.") + return . + + if(!electronics) + . += span_notice("\The [src] needs [span_boldnotice("airlock electronics")] to continue installation, or [span_boldnotice("wirecutters")] to take apart.") + return . + + . += span_notice("\The [src] is ready to be [span_boldnotice("levered")] into place with a [span_boldnotice("crowbar")].") /obj/structure/windoor_assembly/proc/finish_door() var/obj/machinery/door/window/windoor if(secure) windoor = new /obj/machinery/door/window/brigdoor(loc) - if(facing == "l") + if(facing == WINDOOR_LEFT) windoor.icon_state = "leftsecureopen" windoor.base_state = "leftsecure" else @@ -299,7 +365,7 @@ else windoor = new /obj/machinery/door/window(loc) - if(facing == "l") + if(facing == WINDOOR_LEFT) windoor.icon_state = "leftopen" windoor.base_state = "left" else @@ -334,31 +400,12 @@ qdel(src) - -//Flips the windoor assembly, determines whather the door opens to the left or the right -GAME_VERB_SRC(/obj/structure/windoor_assembly, flip, oview(1), "Flip Windoor Assembly", null) - - if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) - return - - if(isliving(usr)) - var/mob/living/L = usr - if(!(L.mobility_flags & MOBILITY_USE)) - return - - if(facing == "l") - to_chat(usr, span_notice("The windoor will now slide to the right.")) - facing = "r" - else - facing = "l" - to_chat(usr, span_notice("The windoor will now slide to the left.")) - - update_appearance() - return - /obj/structure/windoor_assembly/nameformat(input, user) created_name = input return input /obj/structure/windoor_assembly/rename_reset() created_name = initial(created_name) + +#undef WINDOOR_LEFT +#undef WINDOOR_RIGHT diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 6ca6b22836c..36567e7d65d 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -506,6 +506,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/unanchored/spawner, 0) //2021 AND STILLLL GOING STRONG //2022 BABYYYYY ~lewc //2023 ONE YEAR TO GO! -LT3 +//2026 just a week away - kemble /datum/armor/window_reinforced melee = 80 bomb = 25 @@ -517,79 +518,113 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/unanchored/spawner, 0) return list("delay" = 3 SECONDS, "cost" = 15) return FALSE -/obj/structure/window/reinforced/attackby_secondary(obj/item/tool, mob/user, list/modifiers, list/attack_modifiers) +/obj/structure/window/reinforced/item_interaction_secondary(mob/living/user, obj/item/tool, list/modifiers) if(resistance_flags & INDESTRUCTIBLE) balloon_alert(user, "too resilient!") - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ITEM_INTERACT_BLOCKING + + if(!tool.tool_behaviour) + return NONE + // to have gotten to this point, any tool must be innapropriate for its step switch(state) if(RWINDOW_SECURE) - if(tool.tool_behaviour == TOOL_WELDER) - if(tool.tool_start_check(user, heat_required = HIGH_TEMPERATURE_REQUIRED)) - user.visible_message(span_notice("[user] holds \the [tool] to the security screws on \the [src]..."), - span_notice("You begin heating the security screws on \the [src]...")) - if(tool.use_tool(src, user, 15 SECONDS, volume = 100)) - to_chat(user, span_notice("The security screws are glowing white hot and look ready to be removed.")) - state = RWINDOW_BOLTS_HEATED - addtimer(CALLBACK(src, PROC_REF(cool_bolts)), 30 SECONDS) - else if (tool.tool_behaviour) - to_chat(user, span_warning("The security screws need to be heated first!")) + to_chat(user, span_warning("The security screws need to be heated first!")) if(RWINDOW_BOLTS_HEATED) - if(tool.tool_behaviour == TOOL_SCREWDRIVER) - user.visible_message(span_notice("[user] digs into the heated security screws and starts removing them..."), - span_notice("You dig into the heated screws hard and they start turning...")) - if(tool.use_tool(src, user, 50, volume = 50)) - state = RWINDOW_BOLTS_OUT - to_chat(user, span_notice("The screws come out, and a gap forms around the edge of the pane.")) - else if (tool.tool_behaviour) - to_chat(user, span_warning("The security screws need to be removed first!")) + to_chat(user, span_warning("The security screws need to be removed first!")) if(RWINDOW_BOLTS_OUT) - if(tool.tool_behaviour == TOOL_CROWBAR) - user.visible_message(span_notice("[user] wedges \the [tool] into the gap in the frame and starts prying..."), - span_notice("You wedge \the [tool] into the gap in the frame and start prying...")) - if(tool.use_tool(src, user, 40, volume = 50)) - state = RWINDOW_POPPED - to_chat(user, span_notice("The panel pops out of the frame, exposing some thin metal bars that looks like they can be cut.")) - else if (tool.tool_behaviour) - to_chat(user, span_warning("The gap needs to be pried first!")) + to_chat(user, span_warning("The gap needs to be pried first!")) if(RWINDOW_POPPED) - if(tool.tool_behaviour == TOOL_WIRECUTTER) - user.visible_message(span_notice("[user] starts cutting the exposed bars on \the [src]..."), - span_notice("You start cutting the exposed bars on \the [src]")) - if(tool.use_tool(src, user, 20, volume = 50)) - state = RWINDOW_BARS_CUT - to_chat(user, span_notice("The panels falls out of the way exposing the frame bolts.")) - else if (tool.tool_behaviour) - to_chat(user, span_warning("The bars need to be cut first!")) + to_chat(user, span_warning("The bars need to be cut first!")) if(RWINDOW_BARS_CUT) - if(tool.tool_behaviour == TOOL_WRENCH) - user.visible_message(span_notice("[user] starts unfastening \the [src] from the frame..."), - span_notice("You start unfastening the bolts from the frame...")) - if(tool.use_tool(src, user, 40, volume = 50)) - to_chat(user, span_notice("You unscrew the bolts from the frame and the window pops loose.")) - state = WINDOW_OUT_OF_FRAME - set_anchored(FALSE) - else if (tool.tool_behaviour) - to_chat(user, span_warning("The bolts need to be loosened first!")) + to_chat(user, span_warning("The bolts need to be loosened first!")) - - if (tool.tool_behaviour) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - - return ..() + return ITEM_INTERACT_BLOCKING /obj/structure/window/reinforced/crowbar_act(mob/living/user, obj/item/tool) if(!anchored) - return FALSE + return NONE if(state != WINDOW_OUT_OF_FRAME) - return FALSE + return NONE to_chat(user, span_notice("You begin to lever the window back into the frame...")) - if(tool.use_tool(src, user, 10 SECONDS, volume = 75, extra_checks = CALLBACK(src, PROC_REF(check_state_and_anchored), state, anchored))) - state = RWINDOW_SECURE - to_chat(user, span_notice("You pry the window back into the frame.")) + if(!tool.use_tool(src, user, 10 SECONDS, volume = 75, extra_checks = CALLBACK(src, PROC_REF(check_state_and_anchored), state, anchored))) + return ITEM_INTERACT_BLOCKING + + state = RWINDOW_SECURE + to_chat(user, span_notice("You pry the window back into the frame.")) + return ITEM_INTERACT_SUCCESS + +/obj/structure/window/reinforced/welder_act_secondary(mob/living/user, obj/item/tool) + if(state != RWINDOW_SECURE) + return NONE // we got all that messaging for innapropriate tools, no skip to attack + + if(!tool.tool_start_check(user, heat_required = HIGH_TEMPERATURE_REQUIRED)) + return ITEM_INTERACT_BLOCKING + + user.visible_message(span_notice("[user] holds \the [tool] to the security screws on \the [src]..."), + span_notice("You begin heating the security screws on \the [src]...")) + if(!tool.use_tool(src, user, 15 SECONDS, volume = 100)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("The security screws are glowing white hot and look ready to be removed.")) + state = RWINDOW_BOLTS_HEATED + addtimer(CALLBACK(src, PROC_REF(cool_bolts)), 30 SECONDS) + return ITEM_INTERACT_SUCCESS + +/obj/structure/window/reinforced/screwdriver_act_secondary(mob/living/user, obj/item/tool) + if(state != RWINDOW_BOLTS_HEATED) + return NONE + + user.visible_message(span_notice("[user] digs into the heated security screws and starts removing them..."), + span_notice("You dig into the heated screws hard and they start turning...")) + if(!tool.use_tool(src, user, 5 SECONDS, volume = 50)) + return ITEM_INTERACT_BLOCKING + + state = RWINDOW_BOLTS_OUT + to_chat(user, span_notice("The screws come out, and a gap forms around the edge of the pane.")) + return ITEM_INTERACT_SUCCESS + +/obj/structure/window/reinforced/crowbar_act_secondary(mob/living/user, obj/item/tool) + if(state != RWINDOW_BOLTS_OUT) + return NONE + + user.visible_message(span_notice("[user] wedges \the [tool] into the gap in the frame and starts prying..."), + span_notice("You wedge \the [tool] into the gap in the frame and start prying...")) + if(!tool.use_tool(src, user, 4 SECONDS, volume = 50)) + return ITEM_INTERACT_BLOCKING + + state = RWINDOW_POPPED + to_chat(user, span_notice("The panel pops out of the frame, exposing some thin metal bars that looks like they can be cut.")) + return ITEM_INTERACT_SUCCESS + +/obj/structure/window/reinforced/wirecutter_act_secondary(mob/living/user, obj/item/tool) + if(state != RWINDOW_POPPED) + return NONE + + user.visible_message(span_notice("[user] starts cutting the exposed bars on \the [src]..."), + span_notice("You start cutting the exposed bars on \the [src]")) + if(!tool.use_tool(src, user, 2 SECONDS, volume = 50)) + return ITEM_INTERACT_BLOCKING + + state = RWINDOW_BARS_CUT + to_chat(user, span_notice("The panels falls out of the way exposing the frame bolts.")) + return ITEM_INTERACT_SUCCESS + +/obj/structure/window/reinforced/wrench_act_secondary(mob/living/user, obj/item/tool) + if(state != RWINDOW_BARS_CUT) + return NONE + + user.visible_message(span_notice("[user] starts unfastening \the [src] from the frame..."), + span_notice("You start unfastening the bolts from the frame...")) + if(!tool.use_tool(src, user, 4 SECONDS, volume = 50)) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You unscrew the bolts from the frame and the window pops loose.")) + state = WINDOW_OUT_OF_FRAME + set_anchored(FALSE) return ITEM_INTERACT_SUCCESS /obj/structure/window/proc/cool_bolts() @@ -980,25 +1015,27 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/reinforced/tinted/frosted/spaw . = ..() . += (atom_integrity < max_integrity) ? torn : paper -/obj/structure/window/paperframe/attackby(obj/item/W, mob/living/user) - if(W.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) - fire_act(W.get_temperature()) - return +/obj/structure/window/paperframe/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(tool.get_temperature() >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + fire_act(tool.get_temperature()) + return ITEM_INTERACT_SUCCESS if(user.combat_mode) - return ..() + return NONE - if(istype(W, /obj/item/paper) && atom_integrity < max_integrity) - user.visible_message(span_notice("[user] starts to patch the holes in \the [src].")) - if(do_after(user, 2 SECONDS, target = src)) - atom_integrity = min(atom_integrity+4,max_integrity) - qdel(W) - user.visible_message(span_notice("[user] patches some of the holes in \the [src].")) - if(atom_integrity == max_integrity) - update_appearance() - return - ..() - update_appearance() + if(!istype(tool, /obj/item/paper) || atom_integrity == max_integrity) + return NONE + + user.visible_message(span_notice("[user] starts to patch the holes in \the [src].")) + if(!do_after(user, 2 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + + atom_integrity = min(atom_integrity+4,max_integrity) + qdel(tool) + user.visible_message(span_notice("[user] patches some of the holes in \the [src].")) + if(atom_integrity == max_integrity) + update_appearance() + return ITEM_INTERACT_SUCCESS /obj/structure/window/bronze name = "brass window"