Moves a greater manyer morer things from attackby() to item_interaction() (#96739)

## About The Pull Request

50 files, plus additonal file that was necessary because I slightly
refactored windoor construction. This ended up like three and a half
times larger than most of the other ones, I really wasn't meaning for
that to happen. Maybe its because I more vigorously enforced the empty
line after every return thing. The only way to find out is to read 1700
lines of changes, and I don't feel like doing that again. I pinky
promise it all works, and I've tested every item changed individually.

Changes beyond conversion:
You can't welder down reinforced falsewalls anymore, pretty sure it was
an oversight because they're supposed to be taken down by wirecutters
You can right click to close gun lockers with an empty hand, because
otherwise you can't close the lockers at all if there's a gun in them
Meatspikes no longer runtime on construction due to the old trick of
balloon alert + qdel
Windoor assembly no longer SUCKS DICK!!, it's no longer storing
essentially a boolean in an undocumented number in a string, it no
longer requires a VERB to flip its direction.
on a related note, the creator of the windoor assembly construction
steps has been sent to live on a farm far out in the country

Also, a quick note about how these prs are gonna fuck everything up
until they're all together. There's a lot more places where `attackby()`
is directly called than I would have assumed, and given as those are
being changed to call `item_interaction()` potentially(usually) in a
different pr than the pr in which that atom's `attackby()` is actually
converted, that function's not going to work at all until both are
merged. The good news is that almost every instance this is happening,
it's pure convenience, where the user would have access to both items
anyway and could just manually call the attack chain by clicking them
together. Instances where this is not the case are being skipped over
until they can be packaged together to avoid the issue, but I'm not
bothering to do this on ones where the desync won't make an interaction
actually unusable, because that would require me to turn a 1700 line pr
into a 3500 line pr and I really was aiming for like 500

## Why It's Good For The Game

Ignore the paragraph about how I expect this to create a hostage
situation where the only fix to the bugs I make is to merge my other
prs, and instead think about how cool swing combat would be and how much
you want it

## Changelog
🆑
fix: you now can only use a wirecutter to take down a reinforced
falsewall
fix: meatspikes no longer runtime on construction
fix: you no longer have to use a verb that you can't use to flip windoor
assemblies

qol: you can right click a gun locker to close it

code: 50 files have been moved from attackby() to item_interaction()
/🆑
This commit is contained in:
Leland Kemble
2026-07-16 15:07:43 +02:00
committed by GitHub
parent 8586a2eb08
commit 06608081d2
51 changed files with 1697 additions and 1333 deletions
+5 -6
View File
@@ -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)
..()
+21 -17
View File
@@ -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)
+22 -21
View File
@@ -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)
@@ -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)
@@ -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())
+31 -26
View File
@@ -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))
+30 -27
View File
@@ -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()
@@ -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
+18 -13
View File
@@ -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)
..()
@@ -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)
@@ -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.
+46 -38
View File
@@ -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
+33 -31
View File
@@ -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)
+28 -20
View File
@@ -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)
. = ..()
+35 -27
View File
@@ -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"
+5 -5
View File
@@ -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)
. = ..()
+27 -25
View File
@@ -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)
. = ..()
+117 -79
View File
@@ -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)
. = ..()
+210 -146
View File
@@ -83,176 +83,99 @@
if(created_name)
. += span_notice("There is a small <i>paper</i> 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
+8 -8
View File
@@ -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)
@@ -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
+15 -13
View File
@@ -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 <b>grille</b> 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
+28 -27
View File
@@ -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)
+56 -35
View File
@@ -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)
+24 -21
View File
@@ -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)
. = ..()
+13 -11
View File
@@ -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.
+64 -54
View File
@@ -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)
+41 -39
View File
@@ -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!"))
+23 -13
View File
@@ -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
*
+66 -56
View File
@@ -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)
. = ..()
+15 -12
View File
@@ -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"
+8 -7
View File
@@ -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))
+25 -19
View File
@@ -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)
. = ..()
+23 -21
View File
@@ -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 ..()
+7 -5
View File
@@ -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)
+20 -15
View File
@@ -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
@@ -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)
. = ..()
+22 -16
View File
@@ -82,34 +82,40 @@
else
. += span_notice("The railing is <i>unbolted</i> from the floor and can be deconstructed with <b>wirecutters</b>.")
/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
+34 -26
View File
@@ -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)
+21 -18
View File
@@ -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
+20 -18
View File
@@ -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)
. = ..()
+4 -6
View File
@@ -39,13 +39,11 @@
else
. += span_notice("It looks like you could probably scan and tag it with a <b>[scanner_descriptor]</b>.")
/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)
+25 -14
View File
@@ -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)
+19 -21
View File
@@ -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)
+20 -10
View File
@@ -45,17 +45,27 @@
. += span_notice("It is empty.")
. += span_notice("It is held together by some <b>screws</b>.")
/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(..())
@@ -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 ..()
@@ -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
+15 -11
View File
@@ -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)
..()
+248 -201
View File
@@ -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
+108 -71
View File
@@ -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"