diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 816ca918e21..68faddd289f 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -19,8 +19,11 @@ density = TRUE max_integrity = 100 var/proj_pass_rate = 50 //How many projectiles will pass the cover. Lower means stronger cover + /// Used to exclude welders from fixing non metal barricades. var/bar_material = METAL + /// How much material will be dropped on deconstruction? var/drop_amount = 3 + /// What material is the barricade made of? var/stacktype = /obj/item/stack/sheet/metal /// This variable is used to allow projectiles to always shoot through a barrier from a certain direction var/directional_blockage = FALSE @@ -32,9 +35,9 @@ AddComponent(/datum/component/debris, DEBRIS_WOOD, -20, 10) /obj/structure/barricade/deconstruct(disassembled = TRUE) + . = ..() if(!(flags & NODECONSTRUCT)) make_debris() - qdel(src) /obj/structure/barricade/proc/make_debris() if(stacktype) @@ -91,46 +94,114 @@ icon_state = "woodenbarricade" bar_material = WOOD stacktype = /obj/item/stack/sheet/wood + drop_amount = 5 + layer = DOOR_HELPER_LAYER /obj/structure/barricade/wooden/item_interaction(mob/living/user, obj/item/I, list/modifiers) - if(istype(I,/obj/item/stack/sheet/wood)) - var/obj/item/stack/sheet/wood/W = I - if(W.get_amount() < 5) - to_chat(user, SPAN_WARNING("You need at least five wooden planks to make a wall!")) - return ITEM_INTERACT_COMPLETE - else - to_chat(user, SPAN_NOTICE("You start adding [I] to [src]...")) - if(do_after(user, 50, target = src)) - if(!W.use(5)) - return ITEM_INTERACT_COMPLETE - var/turf/T = get_turf(src) - T.ChangeTurf(/turf/simulated/wall/mineral/wood/nonmetal) - qdel(src) - return ITEM_INTERACT_COMPLETE - return ..() + if(!istype(I,/obj/item/stack/sheet/wood)) + return ..() + + var/obj/item/stack/sheet/wood/W = I + if(W.get_amount() < 5) + to_chat(user, SPAN_WARNING("You need at least five wooden planks to make a wall!")) + return ITEM_INTERACT_COMPLETE + + to_chat(user, SPAN_NOTICE("You start adding [I] to [src]...")) + if(!do_after(user, 5 SECONDS, target = src)) + return ITEM_INTERACT_COMPLETE + + if(!W.use(5)) + return ITEM_INTERACT_COMPLETE + + var/turf/T = get_turf(src) + T.ChangeTurf(/turf/simulated/wall/mineral/wood/nonmetal) + qdel(src) + return ITEM_INTERACT_COMPLETE + +// This is for when barricades are initialized on windows or doors to prevent stacking +/obj/structure/barricade/wooden/Initialize(mapload) + . = ..() + for(var/atom/boarded_object as anything in get_turf(src)) + if(istype(boarded_object, /obj/machinery/door)) + var/obj/machinery/door/airlock = boarded_object + airlock.barricaded = TRUE + if(istype(boarded_object, /obj/structure/mineral_door)) + var/obj/structure/mineral_door/door = boarded_object + door.barricaded = TRUE + if(istype(boarded_object, /obj/structure/window/full)) + var/obj/structure/window/full/window = boarded_object + window.barricaded = TRUE + +/obj/structure/barricade/wooden/Destroy() + de_barricade() + ..() /obj/structure/barricade/wooden/crowbar_act(mob/living/user, obj/item/I) . = TRUE if(!I.tool_use_check(user, 0)) return - user.visible_message(SPAN_NOTICE("[user] starts ripping [src] down!"), SPAN_NOTICE("You struggle to pull [src] apart..."), SPAN_WARNING("You hear wood splintering...")) + + user.visible_message( + SPAN_WARNING("[user] starts ripping [src] down!"), + SPAN_NOTICE("You struggle to pull [src] apart..."), + SPAN_WARNING("You hear wood splintering...") + ) if(!I.use_tool(src, user, 6 SECONDS, volume = I.tool_volume)) return - new /obj/item/stack/sheet/wood(get_turf(src), 5) - qdel(src) + + deconstruct() + +/obj/structure/barricade/wooden/proc/de_barricade() + for(var/atom/boarded_object as anything in get_turf(src)) + if(istype(boarded_object, /obj/machinery/door)) + var/obj/machinery/door/airlock = boarded_object + airlock.barricaded = FALSE + if(istype(boarded_object, /obj/structure/mineral_door)) + var/obj/structure/mineral_door/door = boarded_object + door.barricaded = FALSE + if(istype(boarded_object, /obj/structure/window/full)) + var/obj/structure/window/full/window = boarded_object + window.barricaded = FALSE + make_debris() /obj/structure/barricade/wooden/crude name = "crude plank barricade" desc = "This space is blocked off by a crude assortment of planks." icon_state = "woodenbarricade-old" - drop_amount = 1 - max_integrity = 50 + drop_amount = 2 + max_integrity = 75 proj_pass_rate = 65 +// Barricade repairs +/obj/structure/barricade/wooden/crude/item_interaction(mob/living/user, obj/item/I, list/modifiers) + if(!istype(I, /obj/item/stack/sheet/wood)) + return NONE + + if(user.a_intent == INTENT_HARM) + return NONE + + var/obj/item/stack/sheet/wood/S = I + if(obj_integrity >= max_integrity) + to_chat(user, SPAN_NOTICE("[src] is fully intact.")) + return ITEM_INTERACT_COMPLETE + + to_chat(user, SPAN_NOTICE("You start replacing the broken boards of [src]...")) + if(!do_after_once(user, 2 SECONDS, target = src)) + return ITEM_INTERACT_COMPLETE + + if(!S.use(1)) + to_chat(user, SPAN_WARNING("You've run out of planks!")) + return ITEM_INTERACT_COMPLETE + + to_chat(user, SPAN_NOTICE("You repair [src].")) + user.visible_message(SPAN_NOTICE("[user] repairs [src].")) + obj_integrity = max_integrity + add_fingerprint(user) + return ITEM_INTERACT_COMPLETE + /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." icon_state = "woodenbarricade-snow-old" - max_integrity = 75 /obj/structure/barricade/sandbags name = "sandbags" diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 8aadb793b5b..328a37f857f 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -51,6 +51,8 @@ /// How many levels of foam do we have on us? Capped at 5 var/foam_level = 0 + /// Is this door barricaded? + var/barricaded = FALSE /// How much this door reduces superconductivity to when closed. var/superconductivity = DOOR_HEAT_TRANSFER_COEFFICIENT /// So explosion doesn't deal extra damage for multitile airlocks @@ -108,7 +110,7 @@ /obj/machinery/door/Bumped(atom/AM) . = ..() - if(operating || emagged || foam_level) + if(operating || emagged || foam_level || barricaded) return if(ismob(AM)) var/mob/B = AM @@ -170,6 +172,9 @@ if(foam_level) return + if(barricaded) + return + if(density && !emagged) if(allowed(user)) if(HAS_TRAIT(src, TRAIT_CMAGGED)) @@ -195,6 +200,9 @@ if(foam_level) return + if(!barricaded) + return + if(!HAS_TRAIT(user, TRAIT_FORCE_DOORS)) return FALSE @@ -234,7 +242,7 @@ /obj/machinery/door/proc/try_to_activate_door(mob/user) add_fingerprint(user) - if(operating || emagged || foam_level) + if(operating || emagged || foam_level || barricaded) return if(requiresID() && (allowed(user) || user.can_advanced_admin_interact())) if(density) @@ -269,10 +277,14 @@ return /obj/machinery/door/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(istype(used, /obj/item/stack/sheet/wood)) + build_barricade(user, used) + return ITEM_INTERACT_COMPLETE + if(HAS_TRAIT(src, TRAIT_CMAGGED) && used.can_clean()) //If the cmagged door is being hit with cleaning supplies, don't open it, it's being cleaned! return ITEM_INTERACT_SKIP_TO_AFTER_ATTACK - else if(!(used.flags & NOBLUDGEON) && user.a_intent != INTENT_HARM) + if(!(used.flags & NOBLUDGEON) && user.a_intent != INTENT_HARM) try_to_activate_door(user) return ITEM_INTERACT_COMPLETE @@ -281,6 +293,7 @@ /obj/machinery/door/crowbar_act(mob/user, obj/item/I) if(user.a_intent == INTENT_HARM) return + . = TRUE if(operating) return @@ -348,6 +361,40 @@ else close() +/obj/machinery/door/proc/build_barricade(mob/living/user, obj/item/stack/sheet/wood/used) + if(barricaded) + to_chat(user, SPAN_WARNING("[src] is already barricaded!")) + return + + if(used.get_amount() < 2) + to_chat(user, SPAN_WARNING("You need at least two planks of wood to barricade [src]!")) + return + + if(!density) + to_chat(user, SPAN_WARNING("[src] needs to be closed before it can be barricaded!")) + return + + to_chat(user, SPAN_NOTICE("You begin boarding up [src]...")) + if(!do_after_once(user, 4 SECONDS, target = src)) + return + + /// Quick checks to make sure nothing has changed during the timer. + if(!density || barricaded) + return + + if(!used.use(2)) + to_chat(user, SPAN_WARNING("You've run out of planks!")) + return + + user.visible_message( + SPAN_WARNING("[user] boards up [src]!"), + SPAN_NOTICE("You board up [src]."), + SPAN_WARNING("You hear planks being nailed into something!") + ) + var/obj/structure/barricade/wooden/crude/boards = new(loc) + boards.add_fingerprint(user) + barricaded = TRUE + /obj/machinery/door/proc/soundcooldown() if(!sound_ready) return diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 74406c94b80..4857a59cc67 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -25,6 +25,8 @@ var/damageSound = null /// How much foam is on the door. Max 5 levels. var/foam_level = 0 + /// Is this door barricaded? + var/barricaded = FALSE /obj/structure/mineral_door/examine(mob/user) . = ..() @@ -78,6 +80,8 @@ return if(foam_level) return + if(barricaded) + return if(isliving(user)) var/mob/living/M = user if(M.client) @@ -124,7 +128,11 @@ /obj/structure/mineral_door/screwdriver_act(mob/living/user, obj/item/I) if(flags & NODECONSTRUCT) to_chat(user, SPAN_WARNING("You can't figure out how to deconstruct [src]!")) - return TRUE + return COMPONENT_CANCEL_ATTACK_CHAIN + + if(barricaded) + to_chat(user, SPAN_WARNING("There's boards stopping you from levering [src]!")) + return COMPONENT_CANCEL_ATTACK_CHAIN if(!I.use_tool(src, user, 4 SECONDS * I.toolspeed * hardness, volume = I.tool_volume)) return TRUE @@ -132,22 +140,28 @@ deconstruct(TRUE) return TRUE -/obj/structure/mineral_door/item_interaction(mob/living/user, obj/item/W, list/modifiers) - if(istype(W, /obj/item/pickaxe)) +/obj/structure/mineral_door/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(istype(used, /obj/item/stack/sheet/wood)) + build_barricade(user, used) + + if(istype(used, /obj/item/pickaxe)) if(flags & NODECONSTRUCT) to_chat(user, SPAN_WARNING("You can't figure out how to deconstruct [src]!")) - return - var/obj/item/pickaxe/digTool = W + return ITEM_INTERACT_COMPLETE + + var/obj/item/pickaxe/digTool = used to_chat(user, SPAN_NOTICE("You start digging \the [src].")) if(do_after(user, 4 SECONDS * digTool.toolspeed * hardness, target = src) && src) to_chat(user, SPAN_NOTICE("You finished digging.")) deconstruct(TRUE) + return ITEM_INTERACT_COMPLETE - else if(user.a_intent != INTENT_HARM) + + if(user.a_intent != INTENT_HARM) attack_hand(user) return ITEM_INTERACT_COMPLETE - else - return ..() + + return ..() /obj/structure/mineral_door/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT)) @@ -159,6 +173,40 @@ new sheetType(T, max(sheetAmount - 2, 1)) qdel(src) +/obj/structure/mineral_door/proc/build_barricade(mob/living/user, obj/item/stack/sheet/wood/used) + if(barricaded) + to_chat(user, SPAN_WARNING("[src] is already barricaded!")) + return + + if(used.get_amount() < 2) + to_chat(user, SPAN_WARNING("You need at least two planks of wood to barricade [src]!")) + return + + if(!density) + to_chat(user, SPAN_WARNING("[src] needs to be closed before it can be barricaded!")) + return + + to_chat(user, SPAN_NOTICE("You begin boarding up [src]...")) + if(!do_after_once(user, 4 SECONDS, target = src)) + return + + /// Quick checks to make sure nothing has changed during the timer. + if(!density || barricaded) + return + + if(!used.use(2)) + to_chat(user, SPAN_WARNING("You've run out of planks!")) + return + + user.visible_message( + SPAN_WARNING("[user] boards up [src]!"), + SPAN_NOTICE("You board up [src]."), + SPAN_WARNING("You hear planks being nailed into something!") + ) + var/obj/structure/barricade/wooden/crude/boards = new(loc) + boards.add_fingerprint(user) + barricaded = TRUE + /obj/structure/mineral_door/silver name = "silver door" desc = "An old-fashioned door built from two slabs of silver. Somehow completely airtight, and doesn't require any electricity to work." diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index ce0907355e7..c1b4f3e07bc 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -41,7 +41,8 @@ var/superconductivity = WINDOW_HEAT_TRANSFER_COEFFICIENT /// How much we get activated by gamma radiation var/rad_conversion_amount = 0 - + /// Are we boarded up? + var/barricaded = FALSE /obj/structure/window/rad_act(atom/source, amount, emission_type) if(emission_type == GAMMA_RAD && amount * rad_conversion_amount > RAD_BACKGROUND_RADIATION) @@ -219,6 +220,10 @@ return add_fingerprint(user) + if(istype(I, /obj/item/stack/sheet/wood)) + build_barricade(user, I) + return + if(istype(I, /obj/item/stack/rods) && user.a_intent == INTENT_HELP) for(var/obj/structure/grille/G in get_turf(src)) if(!G.broken) @@ -257,7 +262,6 @@ else return ..() - /obj/structure/window/crowbar_act(mob/user, obj/item/I) if(!reinf) return @@ -523,6 +527,43 @@ /obj/structure/window/GetExplosionBlock() return reinf && fulltile ? real_explosion_block : 0 +/obj/structure/window/proc/build_barricade(mob/living/user, obj/item/stack/sheet/wood/used) + if(!fulltile) + return + + if(barricaded) + to_chat(user, SPAN_WARNING("[src] is already barricaded!")) + return + + if(used.get_amount() < 2) + to_chat(user, SPAN_WARNING("You need at least two planks of wood to barricade [src]!")) + return + + if(!density) + to_chat(user, SPAN_WARNING("[src] needs to be secured before it can be barricaded!")) + return + + to_chat(user, SPAN_NOTICE("You begin boarding up [src]...")) + if(!do_after_once(user, 4 SECONDS, target = src)) + return + + /// Quick checks to make sure nothing has changed during the timer. + if(!density || barricaded) + return + + if(!used.use(2)) + to_chat(user, SPAN_WARNING("You've run out of planks!")) + return + + user.visible_message( + SPAN_WARNING("[user] boards up [src]!"), + SPAN_NOTICE("You board up [src]."), + SPAN_WARNING("You hear planks being nailed into something!") + ) + var/obj/structure/barricade/wooden/crude/boards = new(loc) + boards.add_fingerprint(user) + barricaded = TRUE + /obj/structure/window/basic desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it. Lacks protection from radiation." @@ -709,6 +750,20 @@ smoothing_groups = list(SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_REGULAR_WALLS, SMOOTH_GROUP_REINFORCED_WALLS) //they are not walls but this lets walls smooth with them canSmoothWith = list(SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) +/obj/structure/window/full/screwdriver_act(mob/user, obj/item/I) + if(barricaded) + to_chat(user, SPAN_WARNING("There's boards in the way of [src]'s screws!")) + return COMPONENT_CANCEL_ATTACK_CHAIN + + return ..() + +/obj/structure/window/full/crowbar_act(mob/user, obj/item/I) + if(barricaded) + to_chat(user, SPAN_WARNING("There's boards stopping you from levering [src]!")) + return COMPONENT_CANCEL_ATTACK_CHAIN + + return ..() + /obj/structure/window/full/basic desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it. Has very light protection from radiation" icon = 'icons/obj/smooth_structures/windows/window.dmi'