diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm
index bbdd55ab807..cc3c2d821a0 100644
--- a/code/game/objects/effects/chem/foam.dm
+++ b/code/game/objects/effects/chem/foam.dm
@@ -11,6 +11,7 @@
layer = OBJ_LAYER + 0.9
mouse_opacity = 0
animate_movement = 0
+ var/solid_time = 120
var/amount = 3
var/expand = 1
var/metal = 0
@@ -21,7 +22,7 @@
metal = ismetal
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
addtimer(CALLBACK(src, .proc/tick), 3 + metal * 3)
- addtimer(CALLBACK(src, .proc/post), 120)
+ addtimer(CALLBACK(src, .proc/post), solid_time)
/obj/effect/effect/foam/proc/tick()
process()
@@ -81,6 +82,13 @@
var/mob/living/M = AM
M.slip("the foam", 6)
+/obj/effect/effect/foam/spray
+ amount = 1 // only spread a little bit
+ solid_time = 3 SECONDS
+
+/obj/effect/effect/foam/spray/initial
+ amount = 0 // don't spread
+
/datum/effect/effect/system/foam_spread
var/amount = 5 // the size of the foam spread.
var/list/carried_reagents // the IDs of reagents present when the foam was mixed
@@ -157,27 +165,72 @@
qdel(src)
/obj/structure/foamedmetal/attack_hand(var/mob/user)
+ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
+ user.do_attack_animation(src, FIST_ATTACK_ANIMATION)
if ((HULK in user.mutations) || (prob(75 - metal * 25)))
- user.visible_message("[user] smashes through the foamed metal.", "You smash through the metal foam wall.")
+ user.visible_message(SPAN_WARNING("[user] smashes through the foamed metal."), SPAN_NOTICE("You smash through the metal foam wall."))
qdel(src)
else
- to_chat(user, "You hit the metal foam but bounce off it.")
- return
+ to_chat(user, SPAN_NOTICE("You hit the metal foam but bounce off it."))
+ animate_shake()
/obj/structure/foamedmetal/attackby(var/obj/item/I, var/mob/user)
+ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(istype(I, /obj/item/grab))
var/obj/item/grab/G = I
+ if(G.state < GRAB_AGGRESSIVE)
+ to_chat(user, SPAN_WARNING("You need a stronger grip to do that!"))
+ return
G.affecting.forceMove(src.loc)
- visible_message("[G.assailant] smashes [G.affecting] through the foamed metal wall.")
+ visible_message(SPAN_WARNING("[G.assailant] smashes [G.affecting] through the foamed metal wall."))
+ G.affecting.take_overall_damage(15)
qdel(I)
qdel(src)
return
+ else if(istype(I, /obj/item/stack/material))
+ var/obj/item/stack/material/S = I
+ if(S.get_amount() < 4)
+ to_chat(user, SPAN_NOTICE("There isn't enough material here to construct a wall."))
+ return
+
+ var/material/M = SSmaterials.get_material_by_name(S.default_type)
+ if(!istype(M))
+ return
+ if(M.integrity < 50)
+ to_chat(user, SPAN_NOTICE("This material is too soft for use in wall construction."))
+ return
+ user.visible_message("[user] starts slotting material into \the [src]...", SPAN_NOTICE("You start slotting material into \the [src], forming it into a wall..."))
+ if(!do_after(user, 10 SECONDS) || !S.use(4))
+ return
+ var/turf/Tsrc = get_turf(src)
+ var/original_type = Tsrc.type
+ Tsrc.ChangeTurf(/turf/simulated/wall)
+ var/turf/simulated/wall/T = Tsrc
+ T.under_turf = original_type
+ T.set_material(M)
+ T.add_hiddenprint(usr)
+ qdel(src)
+ return
+
+ else if(istype(I, /obj/item/stack/tile/floor))
+ var/turf/T = get_turf(src)
+ if(T.type != /turf/space && !isopenturf(T)) // need to do a hard check here because transit turfs are also space turfs
+ to_chat(user, SPAN_WARNING("The tile below \the [src] isn't an open space, or space itself!"))
+ return
+ var/obj/item/stack/tile/floor/S = I
+ S.use(1)
+ T.ChangeTurf(/turf/simulated/floor/airless)
+ qdel(src)
+ return
+
+ user.do_attack_animation(src, I)
if(prob(I.force * 20 - metal * 25))
- user.visible_message("[user] smashes through the foamed metal.", "You smash through the foamed metal with \the [I].")
+ user.visible_message(SPAN_WARNING("[user] smashes through the foamed metal."), SPAN_NOTICE("You smash through the foamed metal with \the [I]."))
qdel(src)
else
- to_chat(user, "You hit the metal foam to no effect.")
+ to_chat(user, SPAN_NOTICE("You hit the metal foam to no effect."))
+ animate_shake()
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
if(air_group)
diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm
index f68db6cc2e1..f92b5ba500c 100644
--- a/code/modules/clothing/spacesuits/rig/modules/utility.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm
@@ -490,8 +490,6 @@
jets.holder = null
jets.ion_trail.bind(jets)
-/obj/item/rig_module/foam_sprayer
-
/obj/item/rig_module/device/paperdispenser
name = "hardsuit paper dispenser"
desc = "Crisp sheets."
@@ -817,3 +815,47 @@ var/global/list/lattice_users = list()
var/mob/living/carbon/human/H = holder.wearer
to_chat(H, SPAN_NOTICE("Neural lattice disengaged. Pain receptors restored."))
lattice_users.Remove(H)
+
+/obj/item/rig_module/foam_sprayer
+ name = "mounted foam sprayer"
+ desc = "A shoulder-mounted metal foam sprayer."
+ selectable = TRUE
+ icon_state = "actuators"
+
+ interface_name = "integrated foam sprayer"
+ interface_desc = "Projects a line of metal foam where the user selects."
+
+ use_power_cost = 150
+
+ var/spray_distance = 5
+
+ category = MODULE_GENERAL
+
+/obj/item/rig_module/foam_sprayer/engage(atom/target, mob/user)
+ if(!..())
+ return FALSE
+
+ if(!target)
+ return FALSE
+
+ target = get_turf(target)
+ holder.wearer.visible_message("[user] sprays metal foam at \the [target]!", SPAN_NOTICE("You spray metal foam at \the [target]."))
+ var/list/turf_list = getline(user, get_turf(target))
+ turf_list -= turf_list[1] // remove the tile we're on
+ var/counter = spray_distance
+ var/turf/previous_turf
+ for(var/t in turf_list)
+ var/turf/T = t
+ if(!counter)
+ break
+ if(T.contains_dense_objects() || istype(T, /turf/space))
+ break
+ if(previous_turf && LinkBlocked(previous_turf, T))
+ break
+ if(counter == spray_distance)
+ new /obj/effect/effect/foam/spray/initial(t, TRUE)
+ else
+ new /obj/effect/effect/foam/spray(t, TRUE)
+ counter--
+ previous_turf = T
+ sleep(1)
\ No newline at end of file
diff --git a/code/modules/research/designs/mechfab/hardsuit/modules.dm b/code/modules/research/designs/mechfab/hardsuit/modules.dm
index 0a667b3b3f8..7b157ed04bb 100644
--- a/code/modules/research/designs/mechfab/hardsuit/modules.dm
+++ b/code/modules/research/designs/mechfab/hardsuit/modules.dm
@@ -106,4 +106,11 @@
desc = "A heat sink with liquid cooled radiator."
req_tech = list(TECH_MATERIAL = 2, TECH_POWER = 3, TECH_ENGINEERING = 3)
materials = list(DEFAULT_WALL_MATERIAL = 7000, MATERIAL_GLASS = 5500)
- build_path = /obj/item/rig_module/cooling_unit
\ No newline at end of file
+ build_path = /obj/item/rig_module/cooling_unit
+
+/datum/design/hardsuitmodules/foam_sprayer
+ name = "Mounted Foam Sprayer"
+ desc = "A shoulder-mounted metal foam sprayer."
+ req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_POWER = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 15000, MATERIAL_GLASS = 6000)
+ build_path = /obj/item/rig_module/foam_sprayer
\ No newline at end of file
diff --git a/html/changelogs/geeves-foam_time.yml b/html/changelogs/geeves-foam_time.yml
new file mode 100644
index 00000000000..6513d704011
--- /dev/null
+++ b/html/changelogs/geeves-foam_time.yml
@@ -0,0 +1,9 @@
+author: Geeves
+
+delete-after: True
+
+changes:
+ - rscadd: "Added a mounted foam sprayer to the mechfab hardsuit modules tab. It's a hardsuit module that consumes 1500 cell charge to spray a line of metal foam."
+ - rscadd: "Added some effects to metal foam walls that make them a bit more flashy when destroyed, as well as adding a click cooldown so they can't be spammed down."
+ - rscadd: "Aggressively slamming someone through a metal foam wall now does some damage to them."
+ - rscadd: "Clicking on a metal foam wall with building materials will now attempt to turn it into a wall, taking a bit longer than a standard girder would. Clicking on it with a floor tile will now turn it into plating, if the space below is an open space or actual space."
\ No newline at end of file