Planks create barricades on doors/windows and can be crowbarred (#69676)

* Wooden planks can be used on doors/windows to barricade it, using a can_barricade Element.

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
This commit is contained in:
Tim
2022-09-14 22:39:50 -05:00
committed by GitHub
parent 31fe1100aa
commit 4a61f37418
6 changed files with 101 additions and 17 deletions
+64
View File
@@ -0,0 +1,64 @@
#define PLANK_BARRICADE_AMOUNT 2
/datum/element/can_barricade
element_flags = ELEMENT_BESPOKE
id_arg_index = 2
/datum/element/can_barricade/Attach(atom/target)
. = ..()
if(!isatom(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_PARENT_ATTACKBY, .proc/on_start_barricade)
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine)
target.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1
RegisterSignal(target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, .proc/on_requesting_context_from_item)
/datum/element/can_barricade/Detach(atom/target)
UnregisterSignal(target, list(COMSIG_PARENT_ATTACKBY, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM))
// We don't remove HAS_CONTEXTUAL_SCREENTIPS_1, since there could be other stuff still hooked to it,
// and being set without signals is not dangerous, just less performant.
// A lot of things don't do this, perhaps make a proc that checks if any signals are still set, and if not,
// remove the flag.
return ..()
/datum/element/can_barricade/proc/on_examine(atom/source, mob/user, list/examine_texts)
SIGNAL_HANDLER
examine_texts += span_notice("This looks like it can be barricaded with planks of wood.")
/datum/element/can_barricade/proc/on_start_barricade(atom/source, obj/item/stack/sheet/mineral/wood/plank, mob/living/user, params)
SIGNAL_HANDLER
if(user.combat_mode || !istype(plank) || !istype(user))
return
if(plank.get_amount() < PLANK_BARRICADE_AMOUNT)
source.balloon_alert(user, "need [PLANK_BARRICADE_AMOUNT] [plank] sheets!")
return COMPONENT_CANCEL_ATTACK_CHAIN
source.balloon_alert(user, "constructing barricade...")
playsound(source, 'sound/items/hammering_wood.ogg', 50, vary = TRUE)
INVOKE_ASYNC(src, .proc/barricade, source, plank, user, params) //signal handlers can't have do_afters inside of them
return COMPONENT_CANCEL_ATTACK_CHAIN
/// when our element gets attacked by wooden planks it creates a barricade
/datum/element/can_barricade/proc/barricade(atom/source, obj/item/stack/sheet/mineral/wood/plank, mob/living/user, params)
if(!do_after(user, 5 SECONDS, target = source) || !plank.use(2) || (locate(/obj/structure/barricade/wooden/crude) in source.loc))
return
source.balloon_alert(user, "barricade constructed")
var/obj/structure/barricade/wooden/crude/barricade = new (source.loc)
barricade.add_fingerprint(user)
/datum/element/can_barricade/proc/on_requesting_context_from_item(atom/source, list/context, obj/item/held_item, mob/user)
SIGNAL_HANDLER
if(istype(held_item, /obj/item/stack/sheet/mineral/wood) && source.Adjacent(user))
context[SCREENTIP_CONTEXT_LMB] = "Construct barricade"
return CONTEXTUAL_SCREENTIP_SET
return NONE
#undef PLANK_BARRICADE_AMOUNT
+18 -3
View File
@@ -51,10 +51,7 @@
return TRUE
return FALSE
/////BARRICADE TYPES///////
/obj/structure/barricade/wooden
name = "wooden barricade"
desc = "This space is blocked off by a wooden barricade."
@@ -63,6 +60,13 @@
bar_material = WOOD
var/drop_amount = 3
/obj/structure/barricade/wooden/Initialize(mapload)
. = ..()
var/static/list/tool_behaviors = list(TOOL_CROWBAR = list(SCREENTIP_CONTEXT_LMB = "Deconstruct"))
AddElement(/datum/element/contextual_screentip_tools, tool_behaviors)
register_context()
/obj/structure/barricade/wooden/attackby(obj/item/I, mob/user)
if(istype(I,/obj/item/stack/sheet/mineral/wood))
var/obj/item/stack/sheet/mineral/wood/W = I
@@ -71,6 +75,7 @@
return
else
to_chat(user, span_notice("You start adding [I] to [src]..."))
playsound(src, 'sound/items/hammering_wood.ogg', 50, vary = TRUE)
if(do_after(user, 50, target=src))
W.use(5)
var/turf/T = get_turf(src)
@@ -79,6 +84,15 @@
return
return ..()
/obj/structure/barricade/wooden/crowbar_act(mob/living/user, obj/item/tool)
balloon_alert(user, "deconstructing barricade...")
if(!tool.use_tool(src, user, 2 SECONDS, volume=50))
return
balloon_alert(user, "barricade deconstructed")
tool.play_tool_sound(src)
new /obj/item/stack/sheet/mineral/wood(get_turf(src), drop_amount)
qdel(src)
return TOOL_ACT_TOOLTYPE_SUCCESS
/obj/structure/barricade/wooden/crude
name = "crude plank barricade"
@@ -87,6 +101,7 @@
drop_amount = 1
max_integrity = 50
proj_pass_rate = 65
layer = SIGN_LAYER
/obj/structure/barricade/wooden/crude/snow
desc = "This space is blocked off by a crude assortment of planks. It seems to be covered in a layer of snow."
+4 -1
View File
@@ -68,6 +68,7 @@
COMSIG_ATOM_MAGICALLY_UNLOCKED = .proc/on_magic_unlock,
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/can_barricade)
/obj/machinery/door/examine(mob/user)
. = ..()
@@ -87,7 +88,7 @@
if(isaicamera(user) || issilicon(user))
return .
if (isnull(held_item) && Adjacent(user))
if(isnull(held_item) && Adjacent(user))
context[SCREENTIP_CONTEXT_LMB] = "Open"
return CONTEXTUAL_SCREENTIP_SET
@@ -274,6 +275,8 @@
return TRUE
else if(I.item_flags & NOBLUDGEON || user.combat_mode)
return ..()
else if(!user.combat_mode && istype(I, /obj/item/stack/sheet/mineral/wood))
return ..() // we need this so our can_barricade element can be called using COMSIG_PARENT_ATTACKBY
else if(try_to_activate_door(user))
return TRUE
return ..()
+14 -13
View File
@@ -34,19 +34,6 @@
/// If some inconsiderate jerk has had their blood spilled on this window, thus making it cleanable
var/bloodied = FALSE
/obj/structure/window/examine(mob/user)
. = ..()
switch(state)
if(WINDOW_SCREWED_TO_FRAME)
. += span_notice("The window is <b>screwed</b> to the frame.")
if(WINDOW_IN_FRAME)
. += span_notice("The window is <i>unscrewed</i> but <b>pried</b> into the frame.")
if(WINDOW_OUT_OF_FRAME)
if (anchored)
. += span_notice("The window is <b>screwed</b> to the floor.")
else
. += span_notice("The window is <i>unscrewed</i> from the floor, and could be deconstructed by <b>wrenching</b>.")
/obj/structure/window/Initialize(mapload, direct)
. = ..()
if(direct)
@@ -61,6 +48,7 @@
if(fulltile)
setDir()
AddElement(/datum/element/can_barricade)
//windows only block while reinforced and fulltile, so we'll use the proc
real_explosion_block = explosion_block
@@ -78,6 +66,19 @@
if (flags_1 & ON_BORDER_1)
AddElement(/datum/element/connect_loc, loc_connections)
/obj/structure/window/examine(mob/user)
. = ..()
switch(state)
if(WINDOW_SCREWED_TO_FRAME)
. += span_notice("The window is <b>screwed</b> to the frame.")
if(WINDOW_IN_FRAME)
. += span_notice("The window is <i>unscrewed</i> but <b>pried</b> into the frame.")
if(WINDOW_OUT_OF_FRAME)
if (anchored)
. += span_notice("The window is <b>screwed</b> to the floor.")
else
. += span_notice("The window is <i>unscrewed</i> from the floor, and could be deconstructed by <b>wrenching</b>.")
/obj/structure/window/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_DECONSTRUCT)
Binary file not shown.
+1
View File
@@ -987,6 +987,7 @@
#include "code\datums\elements\bed_tucking.dm"
#include "code\datums\elements\bsa_blocker.dm"
#include "code\datums\elements\bump_click.dm"
#include "code\datums\elements\can_barricade.dm"
#include "code\datums\elements\chemical_transfer.dm"
#include "code\datums\elements\chewable.dm"
#include "code\datums\elements\cleaning.dm"