diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm
index fb8cbaf4304..37231b29651 100644
--- a/_maps/map_files/Delta/delta.dmm
+++ b/_maps/map_files/Delta/delta.dmm
@@ -49652,8 +49652,8 @@
/obj/item/radio/intercom{
pixel_y = 28
},
-/obj/machinery/deployable/barrier,
-/obj/machinery/deployable/barrier,
+/obj/item/grenade/barrier,
+/obj/item/grenade/barrier,
/turf/simulated/floor/plasteel{
icon_state = "vault";
dir = 8
@@ -49673,8 +49673,8 @@
},
/area/security/armoury)
"bLK" = (
-/obj/machinery/deployable/barrier,
-/obj/machinery/deployable/barrier,
+/obj/item/grenade/barrier,
+/obj/item/grenade/barrier,
/turf/simulated/floor/plasteel{
icon_state = "vault";
dir = 8
diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
index 5c09a328037..ccfadc2ab79 100644
--- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
@@ -4795,10 +4795,10 @@
/obj/structure/reagent_dispensers/peppertank{
pixel_y = 29
},
-/obj/machinery/deployable/barrier,
-/obj/machinery/deployable/barrier,
-/obj/machinery/deployable/barrier,
-/obj/machinery/deployable/barrier,
+/obj/item/grenade/barrier,
+/obj/item/grenade/barrier,
+/obj/item/grenade/barrier,
+/obj/item/grenade/barrier,
/turf/simulated/floor/plasteel{
tag = "icon-vault (WEST)";
icon_state = "vault";
diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index 661dca15a0e..400641b2631 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -4055,7 +4055,7 @@
/turf/simulated/floor/plasteel,
/area/security/armoury)
"ahH" = (
-/obj/machinery/deployable/barrier,
+/obj/item/grenade/barrier,
/obj/structure/window/reinforced{
dir = 8
},
@@ -4155,7 +4155,7 @@
},
/area/security/brig)
"ahR" = (
-/obj/machinery/deployable/barrier,
+/obj/item/grenade/barrier,
/obj/structure/window/reinforced{
dir = 4
},
@@ -4324,7 +4324,7 @@
},
/area/security/brig)
"aif" = (
-/obj/machinery/deployable/barrier,
+/obj/item/grenade/barrier,
/obj/structure/window/reinforced{
dir = 8
},
@@ -4370,7 +4370,7 @@
},
/area/security/brig)
"aij" = (
-/obj/machinery/deployable/barrier,
+/obj/item/grenade/barrier,
/obj/structure/window/reinforced{
dir = 4
},
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 9345387e304..b540ef16be9 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -482,10 +482,10 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/datum/supply_packs/security/securitybarriers
name = "Security Barriers Crate"
- contains = list(/obj/machinery/deployable/barrier,
- /obj/machinery/deployable/barrier,
- /obj/machinery/deployable/barrier,
- /obj/machinery/deployable/barrier)
+ contains = list(/obj/item/grenade/barrier,
+ /obj/item/grenade/barrier,
+ /obj/item/grenade/barrier,
+ /obj/item/grenade/barrier)
cost = 20
containername = "security barriers crate"
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index e0fb65787cd..af90fad77bf 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -1,144 +1,231 @@
-/*
-CONTAINS:
+#define SINGLE "single"
+#define VERTICAL "vertical"
+#define HORIZONTAL "horizontal"
-Deployable items
-Barricades
+#define METAL 1
+#define WOOD 2
+#define SAND 3
-for reference:
+//Barricades/cover
- access_security = 1
- access_brig = 2
- access_armory = 3
- access_forensics_lockers= 4
- access_medical = 5
- access_morgue = 6
- access_tox = 7
- access_tox_storage = 8
- access_genetics = 9
- access_engine = 10
- access_engine_equip= 11
- access_maint_tunnels = 12
- access_external_airlocks = 13
- access_emergency_storage = 14
- access_change_ids = 15
- access_ai_upload = 16
- access_teleporter = 17
- access_eva = 18
- access_heads = 19
- access_captain = 20
- access_all_personal_lockers = 21
- access_chapel_office = 22
- access_tech_storage = 23
- access_atmospherics = 24
- access_bar = 25
- access_janitor = 26
- access_crematorium = 27
- access_kitchen = 28
- access_robotics = 29
- access_rd = 30
- access_cargo = 31
- access_construction = 32
- access_chemistry = 33
- access_cargo_bot = 34
- access_hydroponics = 35
- access_manufacturing = 36
- access_library = 37
- access_lawyer = 38
- access_virology = 39
- access_cmo = 40
- access_qm = 41
- access_court = 42
- access_clown = 43
- access_mime = 44
-
-*/
-
-
-//Barricades, maybe there will be a metal one later...
/obj/structure/barricade
- anchored = 1.0
- density = 1.0
- var/health = 100.0
- var/maxhealth = 100.0
+ name = "chest high wall"
+ desc = "Looks like this would make good cover."
+ anchored = TRUE
+ density = TRUE
+ max_integrity = 100
+ var/proj_pass_rate = 50 //How many projectiles will pass the cover. Lower means stronger cover
+ var/bar_material = METAL
+ var/drop_amount = 3
var/stacktype = /obj/item/stack/sheet/metal
-/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob, params)
- if(istype(W, stacktype))
- if(src.health < src.maxhealth)
- visible_message("[user] begins to repair the [src]!")
- if(do_after(user, 20 * W.toolspeed, target = src))
- src.health = src.maxhealth
- W:use(1)
- visible_message("[user] repairs the [src]!")
- return
- else
- return
- return
- else if(istype(W, /obj/item/crowbar))
- user.changeNext_move(CLICK_CD_MELEE)
- user.visible_message("[user] is prying apart \the [src].", "You begin to pry apart \the [src].")
- playsound(src, W.usesound, 200, 1)
+/obj/structure/barricade/blob_act(obj/structure/blob/B) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable
+ take_damage(400, BRUTE, "melee", 0, get_dir(src, B))
- if(do_after(user, 300 * W.toolspeed, target = src) && !QDELETED(src))
- user.visible_message("[user] pries apart \the [src].", "You pry apart \the [src].")
- dismantle()
+/obj/structure/barricade/ex_act(severity) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable
+ if(resistance_flags & INDESTRUCTIBLE)
return
- else
- switch(W.damtype)
- if("fire")
- src.health -= W.force * 1
- if("brute")
- src.health -= W.force * 0.75
- else
- if(src.health <= 0)
- visible_message("\The [src] is smashed apart!")
- dismantle()
- ..()
-
-/obj/structure/barricade/ex_act(severity)
switch(severity)
- if(1.0)
- visible_message("\The [src] is blown apart!")
+ if(1)
+ obj_integrity = 0
qdel(src)
- return
- if(2.0)
- src.health -= 25
- if(src.health <= 0)
- visible_message("\The [src] is blown apart!")
- dismantle()
- return
+ if(2)
+ take_damage(rand(100, 250), BRUTE, "bomb", 0)
+ if(3)
+ take_damage(rand(10, 90), BRUTE, "bomb", 0)
-/obj/structure/barricade/blob_act()
- src.health -= 25
- if(src.health <= 0)
- visible_message("The blob eats through \the [src]!")
- qdel(src)
- return
-
-/obj/structure/barricade/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff.
- if(height==0)
- return 1
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return 1
+/obj/structure/barricade/mech_melee_attack(obj/mecha/M) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable
+ M.do_attack_animation(src)
+ var/play_soundeffect = 0
+ var/mech_damtype = M.damtype
+ if(M.selected)
+ mech_damtype = M.selected.damtype
+ play_soundeffect = 1
else
- return 0
+ switch(M.damtype)
+ if(BRUTE)
+ playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
+ if(BURN)
+ playsound(src, 'sound/items/welder.ogg', 50, 1)
+ if(TOX)
+ playsound(src, 'sound/effects/spray2.ogg', 50, 1)
+ return 0
+ else
+ return 0
+ visible_message("[M.name] has hit [src].")
+ return take_damage(M.force*3, mech_damtype, "melee", play_soundeffect, get_dir(src, M)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs.
-/obj/structure/barricade/proc/dismantle()
- if(stacktype)
- new stacktype(get_turf(src))
- new stacktype(get_turf(src))
- new stacktype(get_turf(src))
+/obj/structure/barricade/deconstruct(disassembled = TRUE)
+ make_debris()
qdel(src)
+/obj/structure/barricade/proc/make_debris()
+ if(stacktype)
+ new stacktype(get_turf(src), drop_amount)
+
+/obj/structure/barricade/attackby(obj/item/I, mob/user, params)
+ if(iswelder(I) && user.a_intent != INTENT_HARM && bar_material == METAL)
+ var/obj/item/weldingtool/WT = I
+ if(obj_integrity < max_integrity)
+ if(WT.remove_fuel(0, user))
+ to_chat(user, "You begin repairing [src]...")
+ playsound(loc, WT.usesound, 40, 1)
+ if(do_after(user, 40 * I.toolspeed, target = src))
+ obj_integrity = Clamp(obj_integrity + 20, 0, max_integrity)
+ else
+ return ..()
+
+/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
+ if(locate(/obj/structure/barricade) in get_turf(mover))
+ return TRUE
+ else if(istype(mover, /obj/item/projectile))
+ if(!anchored)
+ return TRUE
+ var/obj/item/projectile/proj = mover
+ if(proj.firer && Adjacent(proj.firer))
+ return TRUE
+ if(prob(proj_pass_rate))
+ return TRUE
+ return FALSE
+ else
+ return !density
+
+
+
+/////BARRICADE TYPES///////
+
/obj/structure/barricade/wooden
name = "wooden barricade"
desc = "This space is blocked off by a wooden barricade."
icon = 'icons/obj/structures.dmi'
icon_state = "woodenbarricade"
+ bar_material = WOOD
stacktype = /obj/item/stack/sheet/wood
burn_state = FLAMMABLE
burntime = 25
+/obj/structure/barricade/wooden/attackby(obj/item/I, mob/user)
+ if(istype(I,/obj/item/stack/sheet/wood))
+ var/obj/item/stack/sheet/wood/W = I
+ if(W.amount < 5)
+ to_chat(user, "You need at least five wooden planks to make a wall!")
+ return
+ else
+ to_chat(user, "You start adding [I] to [src]...")
+ if(do_after(user, 50, target = src))
+ W.use(5)
+ new /turf/simulated/wall/mineral/wood(get_turf(src))
+ qdel(src)
+ return
+ return ..()
+
+/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
+ proj_pass_rate = 65
+
+/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"
+ desc = "Bags of sand. Self explanatory."
+ icon = 'icons/obj/smooth_structures/sandbags.dmi'
+ icon_state = "sandbags"
+ max_integrity = 280
+ proj_pass_rate = 20
+ pass_flags = LETPASSTHROW
+ bar_material = SAND
+ climbable = TRUE
+ smooth = SMOOTH_TRUE
+ canSmoothWith = list(/obj/structure/barricade/sandbags, /turf/simulated/wall, /turf/simulated/wall/r_wall, /obj/structure/falsewall, /obj/structure/falsewall/reinforced, /turf/simulated/wall/rust, /turf/simulated/wall/r_wall/rust, /obj/structure/barricade/security)
+ stacktype = null
+
+/obj/structure/barricade/security
+ name = "security barrier"
+ desc = "A deployable barrier. Provides good cover in fire fights."
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "barrier0"
+ density = FALSE
+ anchored = FALSE
+ max_integrity = 180
+ proj_pass_rate = 20
+ armor = list(melee = 10, bullet = 50, laser = 50, energy = 50, bomb = 10, bio = 100, rad = 100)
+ stacktype = null
+ var/deploy_time = 40
+ var/deploy_message = TRUE
+
+/obj/structure/barricade/security/New()
+ ..()
+ addtimer(CALLBACK(src, .proc/deploy), deploy_time)
+
+/obj/structure/barricade/security/proc/deploy()
+ icon_state = "barrier1"
+ density = TRUE
+ anchored = TRUE
+ if(deploy_message)
+ visible_message("[src] deploys!")
+
+
+/obj/item/grenade/barrier
+ name = "barrier grenade"
+ desc = "Instant cover."
+ icon = 'icons/obj/grenade.dmi'
+ icon_state = "flashbang"
+ item_state = "flashbang"
+ actions_types = list(/datum/action/item_action/toggle_barrier_spread)
+ var/mode = SINGLE
+
+/obj/item/grenade/barrier/examine(mob/user)
+ . = ..()
+ to_chat(user, "Alt-click to toggle modes.")
+
+/obj/item/grenade/barrier/AltClick(mob/living/carbon/user)
+ if(!istype(user) || !user.Adjacent(src) || user.incapacitated())
+ return
+ toggle_mode(user)
+
+/obj/item/grenade/barrier/proc/toggle_mode(mob/user)
+ switch(mode)
+ if(SINGLE)
+ mode = VERTICAL
+ if(VERTICAL)
+ mode = HORIZONTAL
+ if(HORIZONTAL)
+ mode = SINGLE
+
+ to_chat(user, "[src] is now in [mode] mode.")
+
+/obj/item/grenade/barrier/prime()
+ new /obj/structure/barricade/security(get_turf(loc))
+ switch(mode)
+ if(VERTICAL)
+ var/target_turf = get_step(src, NORTH)
+ if(!(is_blocked_turf(target_turf)))
+ new /obj/structure/barricade/security(target_turf)
+
+ var/target_turf2 = get_step(src, SOUTH)
+ if(!(is_blocked_turf(target_turf2)))
+ new /obj/structure/barricade/security(target_turf2)
+ if(HORIZONTAL)
+ var/target_turf = get_step(src, EAST)
+ if(!(is_blocked_turf(target_turf)))
+ new /obj/structure/barricade/security(target_turf)
+
+ var/target_turf2 = get_step(src, WEST)
+ if(!(is_blocked_turf(target_turf2)))
+ new /obj/structure/barricade/security(target_turf2)
+ qdel(src)
+
+/obj/item/grenade/barrier/ui_action_click(mob/user)
+ toggle_mode(user)
+
+
/obj/structure/barricade/mime
name = "floor"
desc = "Is... this a floor?"
@@ -149,128 +236,10 @@ for reference:
/obj/structure/barricade/mime/mrcd
stacktype = null
-//Actual Deployable machinery stuff
+#undef SINGLE
+#undef VERTICAL
+#undef HORIZONTAL
-/obj/machinery/deployable
- name = "deployable"
- desc = "deployable"
- icon = 'icons/obj/objects.dmi'
- req_access = list(access_security)//I'm changing this until these are properly tested./N
-
-/obj/machinery/deployable/barrier
- name = "deployable barrier"
- desc = "A deployable barrier. Swipe your ID card to lock/unlock it."
- icon = 'icons/obj/objects.dmi'
- anchored = 0.0
- density = 1.0
- icon_state = "barrier0"
- var/health = 100.0
- var/maxhealth = 100.0
- var/locked = 0.0
-// req_access = list(access_maint_tunnels)
-
-/obj/machinery/deployable/barrier/New()
- ..()
-
- src.icon_state = "barrier[src.locked]"
-
-/obj/machinery/deployable/barrier/attackby(obj/item/W as obj, mob/user as mob, params)
- if(istype(W, /obj/item/card/id))
- if(src.allowed(user))
- if(src.emagged < 2.0)
- src.locked = !src.locked
- src.anchored = !src.anchored
- src.icon_state = "barrier[src.locked]"
- if((src.locked == 1.0) && (src.emagged < 2.0))
- to_chat(user, "Barrier lock toggled on.")
- return
- else if((src.locked == 0.0) && (src.emagged < 2.0))
- to_chat(user, "Barrier lock toggled off.")
- return
- else
- do_sparks(2, 1, src)
- visible_message("BZZzZZzZZzZT")
- return
- return
- else if(istype(W, /obj/item/wrench))
- if(src.health < src.maxhealth)
- src.health = src.maxhealth
- src.emagged = 0
- src.req_access = list(access_security)
- visible_message("[user] repairs the [src]!")
- return
- else if(src.emagged > 0)
- src.emagged = 0
- src.req_access = list(access_security)
- visible_message("[user] repairs the [src]!")
- return
- return
- else
- switch(W.damtype)
- if("fire")
- src.health -= W.force * 0.75
- if("brute")
- src.health -= W.force * 0.5
- else
- if(src.health <= 0)
- src.explode()
- ..()
-
-/obj/machinery/deployable/barrier/emag_act(user as mob)
- if(!emagged)
- emagged = 1
- req_access = null
- to_chat(user, "You break the ID authentication lock on the [src].")
- do_sparks(2, 1, src)
- visible_message("BZZzZZzZZzZT")
- else if(src.emagged == 1)
- src.emagged = 2
- to_chat(user, "You short out the anchoring mechanism on the [src].")
- do_sparks(2, 1, src)
- visible_message("BZZzZZzZZzZT")
-
-/obj/machinery/deployable/barrier/ex_act(severity)
- switch(severity)
- if(1.0)
- src.explode()
- return
- if(2.0)
- src.health -= 25
- if(src.health <= 0)
- src.explode()
- return
-
-/obj/machinery/deployable/barrier/emp_act(severity)
- if(stat & (BROKEN|NOPOWER))
- return
- if(prob(50/severity))
- locked = !locked
- anchored = !anchored
- icon_state = "barrier[src.locked]"
-
-/obj/machinery/deployable/barrier/blob_act()
- src.health -= 25
- if(src.health <= 0)
- src.explode()
- return
-
-/obj/machinery/deployable/barrier/CanPass(atom/movable/mover, turf/target, height=0)//So bullets will fly over and stuff.
- if(height==0)
- return 1
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return 1
- else
- return 0
-
-/obj/machinery/deployable/barrier/proc/explode()
- visible_message("[src] blows apart!")
- var/turf/Tsec = get_turf(src)
-
-/* var/obj/item/stack/rods/ =*/
- new /obj/item/stack/rods(Tsec)
-
- do_sparks(3, 1, src)
-
- explosion(src.loc,-1,-1,0)
- if(src)
- qdel(src)
+#undef METAL
+#undef WOOD
+#undef SAND
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 0e95f509463..5decbcb7126 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -123,6 +123,19 @@
origin_tech = "biotech=2"
stop_bleeding = 1800
+/obj/item/stack/medical/bruise_pack/attackby(obj/item/I, mob/user, params)
+ if(I.sharp)
+ if(get_amount() < 2)
+ to_chat(user, "You need at least two gauzes to do this!")
+ return
+ new /obj/item/stack/sheet/cloth(user.drop_location())
+ user.visible_message("[user] cuts [src] into pieces of cloth with [I].", \
+ "You cut [src] into pieces of cloth with [I].", \
+ "You hear cutting.")
+ use(2)
+ else
+ return ..()
+
/obj/item/stack/medical/bruise_pack/attack(mob/living/M, mob/user)
if(..())
return 1
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 8c60bcefa11..c9099d6d38b 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -137,6 +137,44 @@ var/global/list/datum/stack_recipe/snow_recipes = list(
..()
recipes = sandstone_recipes
+/*
+ * Sandbags
+ */
+
+/obj/item/stack/sheet/mineral/sandbags
+ name = "sandbags"
+ icon_state = "sandbags"
+ singular_name = "sandbag"
+ layer = LOW_ITEM_LAYER
+ merge_type = /obj/item/stack/sheet/mineral/sandbags
+
+GLOBAL_LIST_INIT(sandbag_recipes, list ( \
+ new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \
+ ))
+
+/obj/item/stack/sheet/mineral/sandbags/New()
+ recipes = GLOB.sandbag_recipes
+ ..()
+
+/obj/item/emptysandbag
+ name = "empty sandbag"
+ desc = "A bag to be filled with sand."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "sandbag"
+ w_class = WEIGHT_CLASS_TINY
+
+/obj/item/emptysandbag/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/stack/ore/glass))
+ var/obj/item/stack/ore/glass/G = I
+ to_chat(user, "You fill the sandbag.")
+ var/obj/item/stack/sheet/mineral/sandbags/S = new /obj/item/stack/sheet/mineral/sandbags(drop_location())
+ qdel(src)
+ if(Adjacent(user) && !issilicon(user))
+ user.put_in_hands(S)
+ G.use(1)
+ else
+ return ..()
+
/obj/item/stack/sheet/mineral/diamond
name = "diamond"
icon_state = "sheet-diamond"
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index f7df69cad2f..50b81717b5f 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -218,6 +218,7 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \
null, \
new/datum/stack_recipe("rag", /obj/item/reagent_containers/glass/rag, 1), \
new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \
+ new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \
null, \
new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \
new/datum/stack_recipe("black gloves", /obj/item/clothing/gloves/color/black, 3), \
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 6fb552654d9..d4e1ed2d7f1 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -1059,6 +1059,15 @@
desc = "A colorful cardboard box for the clown"
icon_state = "box_clown"
+/obj/item/storage/box/emptysandbags
+ name = "box of empty sandbags"
+
+/obj/item/storage/box/emptysandbags/New()
+ ..()
+ contents = list()
+ for(var/i in 1 to 7)
+ new /obj/item/emptysandbag(src)
+
/obj/item/storage/box/rndboards
name = "the Liberator's legacy"
desc = "A box containing a gift for worthy golems."
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 43f45647985..d7900d82e38 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -34,6 +34,15 @@ LINEN BINS
add_fingerprint(user)
return
+/obj/item/bedsheet/attackby(obj/item/I, mob/user, params)
+ if(I.sharp)
+ var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3)
+ transfer_fingerprints_to(C)
+ C.add_fingerprint(user)
+ qdel(src)
+ to_chat(user, "You tear [src] up.")
+ else
+ return ..()
/obj/item/bedsheet/blue
icon_state = "sheetblue"
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index f350633a4c2..b85db884ef5 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -44,8 +44,8 @@
/obj/structure/closet/secure_closet/miner/New()
..()
-// new /obj/item/stack/sheet/mineral/sandbags(src, 5)
-// new /obj/item/storage/box/emptysandbags(src)
+ new /obj/item/stack/sheet/mineral/sandbags(src, 5)
+ new /obj/item/storage/box/emptysandbags(src)
new /obj/item/shovel(src)
new /obj/item/pickaxe/mini(src)
new /obj/item/radio/headset/headset_cargo/mining(src)
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index 23e49287922..ec81f363f14 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/smooth_structures/sandbags.dmi b/icons/obj/smooth_structures/sandbags.dmi
new file mode 100644
index 00000000000..8ac099555a8
Binary files /dev/null and b/icons/obj/smooth_structures/sandbags.dmi differ
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index f30ecfe94d1..d1b6b267f8a 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ