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"