diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm index 69dc941d9ee..8a7cbdc2022 100644 --- a/code/game/machinery/autolathe_datums.dm +++ b/code/game/machinery/autolathe_datums.dm @@ -378,6 +378,11 @@ path = /obj/item/device/destTagger category = "General" +/datum/autolathe/recipe/steelwool + name = "steel wool" + path = /obj/item/steelwool + category = "Tools" + /datum/autolathe/recipe/debugger name = "debugger" path = /obj/item/device/debugger diff --git a/code/game/objects/items/weapons/grenades/fragmentation.dm b/code/game/objects/items/weapons/grenades/fragmentation.dm index 7d37f111df3..b7545ca275a 100644 --- a/code/game/objects/items/weapons/grenades/fragmentation.dm +++ b/code/game/objects/items/weapons/grenades/fragmentation.dm @@ -1,4 +1,4 @@ -proc/fragem(var/source,var/fragx,var/fragy,var/light_dam,var/flash_dam,var/p_dam,var/p_range,var/can_cover=1) +proc/fragem(var/source,var/fragx,var/fragy,var/light_dam,var/flash_dam,var/p_dam,var/p_range,var/can_cover=TRUE,var/shard_range = 50) var/turf/O = get_turf(source) var/fragger = rand(fragx,fragy) explosion(O, -1, -1, light_dam, flash_dam) @@ -13,6 +13,7 @@ proc/fragem(var/source,var/fragx,var/fragy,var/light_dam,var/flash_dam,var/p_dam P.pellets = fragments_per_projectile P.range_step = p_range P.shot_from = source + P.range = shard_range P.name = "shrapnel" P.launch_projectile(T) @@ -55,6 +56,6 @@ proc/fragem(var/source,var/fragx,var/fragy,var/light_dam,var/flash_dam,var/p_dam set waitfor = 0 ..() - fragem(src,num_fragments,num_fragments,explosion_size,explosion_size+1,fragment_damage,damage_step,1) + fragem(src,num_fragments,num_fragments,explosion_size,explosion_size+1,fragment_damage,damage_step,TRUE) qdel(src) diff --git a/code/game/objects/items/weapons/landmines.dm b/code/game/objects/items/weapons/landmines.dm index 8cb14debfd6..d4a674ef475 100644 --- a/code/game/objects/items/weapons/landmines.dm +++ b/code/game/objects/items/weapons/landmines.dm @@ -128,7 +128,7 @@ /obj/item/landmine/frag/trigger(mob/living/L) spark(src, 3, alldirs) - fragem(src,num_fragments,num_fragments,explosion_size,explosion_size+1,fragment_damage,damage_step,1) + fragem(src,num_fragments,num_fragments,explosion_size,explosion_size+1,fragment_damage,damage_step,TRUE) qdel(src) /obj/item/landmine/radiation diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index b57b1c976f7..2f5ee70a475 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -768,3 +768,59 @@ playsound(loc, 'sound/items/change_drill.ogg', 50, 1) update_tool() return TRUE + +/obj/item/steelwool + name = "steel wool" + desc = "Harvested from the finest NanoTrasen steel sheep." + icon = 'icons/obj/tools.dmi' + icon_state = "steel_wool" + flags = NOBLUDGEON + w_class = ITEMSIZE_SMALL + var/lit + matter = list(MATERIAL_STEEL = 40) + +/obj/item/steelwool/isFlameSource() + return lit + +/obj/item/steelwool/attackby(obj/item/W, mob/user) + if(W.isFlameSource()) + ignite(W, user) + else if(istype(W, /obj/item/cell)) + var/obj/item/cell/S = W + if(S.charge) + ignite(W, user) + else + to_chat(user, SPAN_WARNING("The cell isn't charged!")) + +/obj/item/steelwool/fire_act() + ignite() + +/obj/item/steelwool/proc/ignite(var/L, mob/user) + if(lit && user) + to_chat(user, SPAN_WARNING("The steel wool is already lit!")) + return + else + lit = TRUE + if(user) + user.visible_message(SPAN_NOTICE("[user] ignites the steel wool with \the [L]."), SPAN_NOTICE("You ignite the steel wool with \the [L]"), SPAN_NOTICE("You hear a gentle flame crackling.")) + playsound(get_turf(src), 'sound/items/flare.ogg', 50) + desc += " Watch your hands!" + icon_state = "burning_wool" + set_light(2, 2, LIGHT_COLOR_LAVA) + addtimer(CALLBACK(src, .proc/endburn), 120 SECONDS, TIMER_UNIQUE) + +/obj/item/steelwool/proc/endburn() + visible_message(SPAN_NOTICE("The steel wool burns out.")) + if(ishuman(loc)) + var/mob/living/carbon/human/user = loc + if(!user.gloves) + var/UserLoc = get_equip_slot() + if(UserLoc == slot_l_hand) + user.apply_damage(5, BURN, BP_L_HAND) + to_chat(user, SPAN_DANGER("The steel wool burns your left hand!")) + else if(UserLoc == slot_r_hand) + user.apply_damage(5, BURN, BP_R_HAND) + to_chat(user, SPAN_DANGER("The steel wool burns your right hand!")) + + new /obj/effect/decal/cleanable/ash(get_turf(src)) + qdel(src) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index aa916c5d949..1aaca2a2068 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1019,7 +1019,7 @@ /mob/living/silicon/robot/proc/self_destruct() density = FALSE - fragem(src, 50, 100, 2, 1, 5, 1, 0) + fragem(src, 50, 100, 2, 1, 5, 1, FALSE) gib() /mob/living/silicon/robot/update_canmove() // to fix lockdown issues w/ chairs diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index 50da1d7a402..1383f22cde3 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -121,7 +121,7 @@ burst() /mob/living/simple_animal/hostile/hivebot/bomber/proc/burst() - fragem(src,10,30,2,3,5,1,0) + fragem(src,10,30,2,3,5,1,FALSE) src.gib() /mob/living/simple_animal/hostile/hivebot/range diff --git a/code/modules/reagents/reagent_containers/food/cans.dm b/code/modules/reagents/reagent_containers/food/cans.dm index b4a2105ea1f..771a78490ce 100644 --- a/code/modules/reagents/reagent_containers/food/cans.dm +++ b/code/modules/reagents/reagent_containers/food/cans.dm @@ -1,4 +1,18 @@ +#define LETHAL_FUEL_CAPACITY 21 // this many units of fuel will cause a harmful explosion +#define FUSELENGTH_MAX 10 // this is the longest a fuse can be +#define FUSELENGTH_MIN 3 // and the minimum that the builder can intentionally make +#define FUSELENGTH_SHORT 5 // the upper boundary of the short fuse +#define FUSELENGTH_LONG 6 // the lower boundary of the long fuse +#define BOMBCASING_EMPTY 0 // no grenade casing +#define BOMBCASING_LOOSE 1 // it's in a grenade casing but not secured +#define BOMBCASING_SECURE 2 // it's in a grenade casing and secured - shrapnel count increased + /obj/item/reagent_containers/food/drinks/cans + var/fuselength = 0 + var/fuselit + var/bombcasing + var/shrapnelcount = 7 + var/list/can_size_overrides = list("x" = 0, "y" = -3) // position of the can's opening - make sure to take away 16 from X and 23 from Y volume = 40 //just over one and a half cups amount_per_transfer_from_this = 5 flags = 0 //starts closed @@ -24,6 +38,210 @@ return TRUE . = ..() +/obj/item/reagent_containers/food/drinks/cans/update_icon() + cut_overlays() + if(fuselength) + var/image/fuseoverlay = image('icons/obj/fuses.dmi', icon_state = "fuse_short") + switch(fuselength) + if(FUSELENGTH_LONG to INFINITY) + fuseoverlay.icon_state = "fuse_long" + if(fuselit) + fuseoverlay.icon_state = "lit_fuse" + fuseoverlay.pixel_x = can_size_overrides["x"] + fuseoverlay.pixel_y = can_size_overrides["y"] + add_overlay(fuseoverlay) + if(bombcasing > BOMBCASING_EMPTY) + var/image/casingoverlay = image('icons/obj/fuses.dmi', icon_state = "pipe_bomb") + add_overlay(casingoverlay) + +/obj/item/reagent_containers/food/drinks/cans/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/grenade/chem_grenade/large)) + var/obj/item/grenade/chem_grenade/grenade_casing = W + if(!grenade_casing.detonator && !length(grenade_casing.beakers) && bombcasing < BOMBCASING_LOOSE) + bombcasing = BOMBCASING_LOOSE + desc = "A grenade casing with \a [name] slotted into it." + if(fuselength) + desc += " It has some steel wool stuffed into the opening." + user.visible_message(SPAN_NOTICE("[user] slots \the [grenade_casing] over \the [name]."), SPAN_NOTICE("You slot \the [grenade_casing] over \the [name].")) + desc = "A grenade casing with \a [name] slotted into it." + qdel(grenade_casing) + update_icon() + + if(W.isscrewdriver() && bombcasing > BOMBCASING_EMPTY) + if(bombcasing == BOMBCASING_LOOSE) + bombcasing = BOMBCASING_SECURE + shrapnelcount = 14 + user.visible_message(SPAN_NOTICE("[user] tightens the grenade casing around \the [name]."), SPAN_NOTICE("You tighten the grenade casing around \the [name].")) + else if(bombcasing == BOMBCASING_SECURE) + bombcasing = BOMBCASING_EMPTY + shrapnelcount = initial(shrapnelcount) + desc = initial(desc) + if(fuselength) + desc += " It has some steel wool stuffed into the opening." + user.visible_message(SPAN_NOTICE("[user] removes \the [name] from the grenade casing."), SPAN_NOTICE("You remove \the [name] from the grenade casing.")) + new /obj/item/grenade/chem_grenade/large(get_turf(src)) + playsound(loc, W.usesound, 50, 1) + update_icon() + + if(istype(W, /obj/item/steelwool)) + if(is_open_container()) + switch(fuselength) + if(-INFINITY to FUSELENGTH_MAX) + user.visible_message("[user] stuffs some steel wool into \the [name].", SPAN_NOTICE("You feed steel wool into \the [name], ruining it in the process. It will last approximately 10 seconds.")) + fuselength = FUSELENGTH_MAX + update_icon() + desc += " It has some steel wool stuffed into the opening." + if(W.isFlameSource()) + light_fuse(W, user, TRUE) + qdel(W) + if(FUSELENGTH_MAX) + to_chat(user, SPAN_WARNING("You cannot make the fuse longer than 10 seconds!")) + else + to_chat(user, SPAN_WARNING("There is no opening on \the [name] for the steel wool!")) + + else if(W.iswirecutter() && fuselength) + switch(fuselength) + if(1 to FUSELENGTH_MIN) // you can't increase the fuse with wirecutters and you can't trim it down below 3, so just remove it outright. + user.visible_message("[user] removes the steel wool from \the [name].", SPAN_NOTICE("You remove the steel wool fuse from \the [name].")) + FuseRemove() + if(4 to FUSELENGTH_MAX) + var/fchoice = alert("Do you want to shorten or remove the fuse on \the [name]?", "Shorten or Remove", "Shorten", "Remove", "Cancel") + switch(fchoice) + if("Shorten") + var/short = input("How many seconds do you want the fuse to be?", "[name] fuse") as null|num + if(!use_check_and_message(user)) + if(short < fuselength && short >= FUSELENGTH_MIN) + to_chat(user, SPAN_NOTICE("You shorten the fuse to [short] seconds.")) + FuseRemove(fuselength - short) + else if(!short && !isnull(short)) + user.visible_message("[user] removes the steel wool from \the [name]", SPAN_NOTICE("You remove the steel wool fuse from \the [name].")) + FuseRemove() + else if(short == fuselength || isnull(short)) + to_chat(user, SPAN_NOTICE("You decide against modifying the fuse.")) + else if (short > fuselength) + to_chat(user, SPAN_WARNING("You cannot make the fuse longer than it already is!")) + else if(short in list(1,2)) + to_chat(user, SPAN_WARNING("The fuse cannot be shorter than 3 seconds!")) + else + return + if("Remove") + if(!use_check_and_message(user)) + user.visible_message("[user] removes the steel wool from \the [name].", "You remove the steel wool fuse from \the [name].") + FuseRemove() + if("Cancel") + return + return + + else if(W.isFlameSource() && fuselength) + light_fuse(W, user) + . = ..() + +/obj/item/reagent_containers/food/drinks/cans/proc/light_fuse(obj/item/W, mob/user, var/premature=FALSE) + if(can_light()) + fuselit = TRUE + update_icon() + set_light(2, 2, LIGHT_COLOR_LAVA) + if(reagents.get_reagent_amount(/datum/reagent/fuel) >= LETHAL_FUEL_CAPACITY && user) + msg_admin_attack("[user] ([user.ckey]) lit the fuse on an improvised [name] grenade. (JMP)",ckey=key_name(user)) + if(fuselength >= FUSELENGTH_MIN && fuselength <= FUSELENGTH_SHORT) + user.visible_message(SPAN_DANGER("[user] accidentally takes \the [W] too close to \the [name]'s opening!")) + detonate(TRUE) // it'd be a bit dull if the toy-levels of fuel had a chance to insta-pop, it's mostly just a way to keep the grenade balance in check + if(fuselength < FUSELENGTH_MIN) + user.visible_message(SPAN_DANGER("[user] tries to light the fuse on \the [name] but it was too short!"), SPAN_DANGER("You try to light the fuse but it was too short!")) + detonate(TRUE) // if you're somehow THAT determined and/or ignorant you managed to get the fuse below 3 seconds, so be it. reap what you sow. + else + if(premature) + user.visible_message(SPAN_WARNING("[user] prematurely starts \the [name]'s fuse!"), SPAN_WARNING("You prematurely start \the [name]'s fuse!")) + else + user.visible_message(SPAN_WARNING("[user] lights the steel wool on \the [name] with \the [W]!"), SPAN_WARNING("You light the steel wool on \the [name] with the [W]!")) + playsound(get_turf(src), 'sound/items/flare.ogg', 50) + detonate(FALSE) + +/obj/item/reagent_containers/food/drinks/cans/proc/detonate(var/instant) + var/fuel = reagents.get_reagent_amount(/datum/reagent/fuel) + if(instant) + fuselength = 0 + else if(prob(fuselength * 6)) // the longer the fuse, the higher chance it will fizzle out (18% chance minimum) + var/fizzle = rand(1, fuselength - 1) + sleep(fizzle * 1 SECOND) + + fuselength -= fizzle + visible_message(SPAN_WARNING("The fuse on \the [name] fizzles out early.")) + playsound(get_turf(src), 'sound/items/cigs_lighters/cig_snuff.ogg', 50) + fuselit = FALSE + set_light(0, 0) + update_icon() + return + else + fuselength += rand(-2, 2) // if the fuse isn't fizzling out or detonating instantly, make it a little harder to predict the fuse by +2/-2 seconds + sleep(fuselength * 1 SECOND) + + switch(round(fuel)) + if(0) + visible_message(SPAN_NOTICE("\The [name]'s fuse burns out and nothing happens.")) + fuselength = 0 + fuselit = FALSE + update_icon() + set_light(0, 0) + return + if(1 to FUSELENGTH_MAX) // baby explosion. + var/obj/item/trash/can/popped_can = new(get_turf(src)) + popped_can.icon_state = icon_state + popped_can.name = "popped can" + playsound(get_turf(src), 'sound/effects/snap.ogg', 50) + visible_message(SPAN_WARNING("\The [name] pops harmlessly!")) + if(11 to 20) // slightly less baby explosion + new /obj/item/material/shard/shrapnel(get_turf(src)) + playsound(get_turf(src), 'sound/effects/bang.ogg', 50) + visible_message(SPAN_WARNING("\The [name] bursts violently into pieces!")) + if(LETHAL_FUEL_CAPACITY to INFINITY) // boom + fragem(src, shrapnelcount, shrapnelcount, 1, 0, 5, 1, TRUE, 2) // The main aim of the grenade should be to hit and wound people with shrapnel instead of causing a lot of station damage, hence the small explosion radius + playsound(get_turf(src), 'sound/effects/Explosion1.ogg', 50) + visible_message(SPAN_DANGER("\The [name] explodes!")) + fuselit = FALSE + update_icon() + qdel(src) + +/obj/item/reagent_containers/food/drinks/cans/proc/can_light() // just reverses the fuselit var to return a TRUE or FALSE, should hopefully make things a little easier if someone adds more fuse interactions later. + return !fuselit && fuselength + +/obj/item/reagent_containers/food/drinks/cans/proc/FuseRemove(var/CableRemoved = fuselength) + fuselength -= CableRemoved + update_icon() + if(!fuselength) + if(bombcasing > BOMBCASING_EMPTY) + desc = "A grenade casing with \a [name] slotted into it." + else + desc = initial(desc) + +/obj/item/reagent_containers/food/drinks/cans/bullet_act(obj/item/projectile/P) + if(P.firer && reagents.get_reagent_amount(/datum/reagent/fuel) >= LETHAL_FUEL_CAPACITY) + visible_message(SPAN_DANGER("\The [name] is hit by the [P]!")) + log_and_message_admins("shot an improvised [name] explosive", P.firer) + log_game("[key_name(P.firer)] shot improvised grenade at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).",ckey=key_name(P.firer)) + detonate(TRUE) + . = ..() + +/obj/item/reagent_containers/food/drinks/cans/ex_act(severity) + detonate(TRUE) + . = ..() + +/obj/item/reagent_containers/food/drinks/cans/fire_act() + if(can_light()) + fuselit = TRUE + detonate(FALSE) + visible_message(SPAN_WARNING("\The [name]'s fuse catches on fire!")) + . = ..() + +#undef LETHAL_FUEL_CAPACITY +#undef FUSELENGTH_MAX +#undef FUSELENGTH_MIN +#undef FUSELENGTH_SHORT +#undef FUSELENGTH_LONG +#undef BOMBCASING_EMPTY +#undef BOMBCASING_LOOSE +#undef BOMBCASING_SECURE + //DRINKS /obj/item/reagent_containers/food/drinks/cans/cola @@ -118,7 +336,7 @@ desc = "A radical looking can of Phoron Punch! Phoron poisoning has never been more extreme!" icon_state = "phoron_punch" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/kois/clean = 10, /datum/reagent/toxin/phoron = 5) /obj/item/reagent_containers/food/drinks/cans/root_beer @@ -136,7 +354,7 @@ desc = "A can of cherry energy drink, with V'krexi additives. All good colas come in cherry." icon_state = "zoracherry" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda = 20, /datum/reagent/mental/vaam = 15) /obj/item/reagent_containers/food/drinks/cans/zorakois @@ -144,7 +362,7 @@ desc = "A can of K'ois flavored energy drink, with V'krexi additives. Contains no K'ois, probably contains no palatable flavor." icon_state = "koistwist" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda/kois = 20, /datum/reagent/mental/vaam = 15) /obj/item/reagent_containers/food/drinks/cans/zoraphoron @@ -152,7 +370,7 @@ desc = "A can of grape flavored energy drink, with V'krexi additives. Tastes nothing like phoron according to Unbound taste testers." icon_state = "phoronpassion" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda/phoron = 20, /datum/reagent/mental/vaam = 15) /obj/item/reagent_containers/food/drinks/cans/zorahozm @@ -160,7 +378,7 @@ desc = "A can of fizzy, acidic energy, with plenty of V'krexi additives. Tastes like impaling the bottom of your mouth with a freezing cold spear laced with bees and salt." icon_state = "hozm" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda/hozm = 20, /datum/reagent/mental/vaam = 15) /obj/item/reagent_containers/food/drinks/cans/zoravenom @@ -168,7 +386,7 @@ desc = "A diet can of Venom Grass flavored energy drink, with V'krexi additives. Still tastes like a cloud of stinging polytrinic bees, but calories are nowhere to be found." icon_state = "sourvenomgrass" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda/venomgrass = 20, /datum/reagent/mental/vaam = 15) /obj/item/reagent_containers/food/drinks/cans/zoraklax @@ -176,7 +394,7 @@ desc = "A can of orange cream flavored energy drink, with V'krexi additives. Engineered nearly to perfection." icon_state = "klaxancrush" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda/klax = 20, /datum/reagent/mental/vaam = 15) /obj/item/reagent_containers/food/drinks/cans/zoracthur @@ -184,7 +402,7 @@ desc = "A can of blue raspberry flavored energy drink, with V'krexi additives. You're pretty sure this was shipped by mistake, the previous K'laxan Energy Crush wrapper is still partly visible underneath the current one." icon_state = "cthurberry" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda/cthur = 20, /datum/reagent/mental/vaam = 15) /obj/item/reagent_containers/food/drinks/cans/zoradrone @@ -192,7 +410,7 @@ desc = "A can of some kind of industrial fluid flavored energy drink, with V'krexi additives meant for Vaurca. Known to induce vomiting in humans!." icon_state = "dronefuel" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda/drone = 30, /datum/reagent/mental/vaam = 10) /obj/item/reagent_containers/food/drinks/cans/zorajelly @@ -200,7 +418,7 @@ desc = "A can of... You aren't sure, but it smells pleasant already." icon_state = "royaljelly" center_of_mass = list("x"=16, "y"=8) - + can_size_overrides = list("x" = 1) reagents_to_add = list(/datum/reagent/drink/zorasoda/jelly = 30) /obj/item/reagent_containers/food/drinks/cans/adhomai_milk @@ -218,6 +436,7 @@ icon_state = "beetlemilk" center_of_mass = list("x"=17, "y"=10) reagents_to_add = list(/datum/reagent/drink/milk/beetle = 30) + can_size_overrides = list("x" = 1, "y" = -2) /obj/item/reagent_containers/food/drinks/cans/dyn name = "Cooling Breeze" @@ -231,4 +450,4 @@ desc = "A cider made on the west coast of the Moghresian Sea, this is simply one of many brands made in a region known for its craft local butanol, shipped throughout the Wasteland." icon_state = "three_towns_cider" center_of_mass = list("x"=16, "y"=10) - reagents_to_add = list(/datum/reagent/alcohol/butanol/threetownscider = 30) \ No newline at end of file + reagents_to_add = list(/datum/reagent/alcohol/butanol/threetownscider = 30) diff --git a/html/changelogs/hockaa-weldercansfix.yml b/html/changelogs/hockaa-weldercansfix.yml new file mode 100644 index 00000000000..3ff6ce363f9 --- /dev/null +++ b/html/changelogs/hockaa-weldercansfix.yml @@ -0,0 +1,7 @@ +author: Hocka, Happy_Fox + +delete-after: True + +changes: + - rscadd: "Added steel wool which can be ignited with a cell/other flame source to briefly light up an area, as well as light other things. Can be obtained via autolathe." + - rscadd: "Empty cans can now be turned into jury-rigged shrapnel grenades which are made by filling cans with welding fuel, adding a fuse with steel wool and lighting it using a flame source. Shorter fuses have a chance to instantly detonate and longer fuses can fizzle out prematurely. Large grenade casings can be used to increase the amount of shrapnel." \ No newline at end of file diff --git a/icons/obj/fuses.dmi b/icons/obj/fuses.dmi new file mode 100644 index 00000000000..6525b683aa7 Binary files /dev/null and b/icons/obj/fuses.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index d904c06ec7a..665b0379b6b 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ