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"