diff --git a/baystation12.dme b/baystation12.dme
index 53bceb1117e..586f183ae02 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -477,6 +477,7 @@
#include "code\game\machinery\kitchen\smartfridge.dm"
#include "code\game\machinery\pipe\construction.dm"
#include "code\game\machinery\pipe\pipe_dispenser.dm"
+#include "code\game\machinery\pipe\pipelayer.dm"
#include "code\game\machinery\telecomms\broadcaster.dm"
#include "code\game\machinery\telecomms\logbrowser.dm"
#include "code\game\machinery\telecomms\machine_interactions.dm"
diff --git a/code/game/machinery/pipe/pipelayer.dm b/code/game/machinery/pipe/pipelayer.dm
new file mode 100644
index 00000000000..32aafb21cd8
--- /dev/null
+++ b/code/game/machinery/pipe/pipelayer.dm
@@ -0,0 +1,137 @@
+/obj/machinery/pipelayer
+
+ name = "automatic pipe layer"
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "pipe_d"
+ density = 1
+ var/turf/old_turf
+ var/old_dir
+ var/on = 0
+ var/a_dis = 0
+ var/P_type = 0
+ var/P_type_t = ""
+ var/max_metal = 50
+ var/metal = 10
+ var/obj/item/weapon/wrench/W
+ var/list/Pipes = list("regular pipes"=0,"scrubbers pipes"=31,"supply pipes"=29,"heat exchange pipes"=2)
+
+/obj/machinery/pipelayer/New()
+ W = new(src)
+ ..()
+
+/obj/machinery/pipelayer/Move(new_turf,M_Dir)
+ ..()
+
+ if(on && a_dis)
+ dismantleFloor(old_turf)
+ layPipe(old_turf,M_Dir,old_dir)
+
+ old_turf = new_turf
+ old_dir = turn(M_Dir,180)
+
+/obj/machinery/pipelayer/attack_hand(mob/user as mob)
+ if(!metal&&!on)
+ user << "\The [src] doesn't work without metal."
+ return
+ on=!on
+ user.visible_message("[user] has [!on?"de":""]activated \the [src].", "You [!on?"de":""]activate \the [src].")
+ return
+
+/obj/machinery/pipelayer/attackby(var/obj/item/W as obj, var/mob/user as mob)
+
+ if (istype(W, /obj/item/weapon/wrench))
+ P_type_t = input("Choose pipe type", "Pipe type") as null|anything in Pipes
+ P_type = Pipes[P_type_t]
+ user.visible_message("[user] has set \the [src] to manufacture [P_type_t].", "You set \the [src] to manufacture [P_type_t].")
+ return
+
+ if(istype(W, /obj/item/weapon/crowbar))
+ a_dis=!a_dis
+ user.visible_message("[user] has [!a_dis?"de":""]activated auto-dismantling.", "You [!a_dis?"de":""]activate auto-dismantling.")
+ return
+
+ if(istype(W, /obj/item/stack/sheet/metal))
+
+ var/result = load_metal(W)
+ if(isnull(result))
+ user << "Unable to load [W] - no metal found."
+ else if(!result)
+ user << "\The [src] is full."
+ else
+ user.visible_message("[user] has loaded metal into \the [src].", "You load metal into \the [src]")
+
+ return
+
+ if(istype(W, /obj/item/weapon/screwdriver))
+ if(metal)
+ var/m = round(input(usr,"Please specify the amount of metal to remove","Remove metal",min(round(metal),50)) as num, 1)
+ m = min(m, 50)
+ m = min(m, round(metal))
+ m = round(m)
+ if(m)
+ use_metal(m)
+ var/obj/item/stack/sheet/metal/MM = new (get_turf(src))
+ MM.amount = m
+ user.visible_message("[user] removes [m] sheet\s of metal from the \the [src].", "You remove [m] sheet\s of metal from \the [src]")
+ else
+ user << "\The [src] is empty."
+ return
+ ..()
+
+/obj/machinery/pipelayer/examine(mob/user)
+ ..()
+ user << "\The [src] has [metal] sheet\s, is set to produce [P_type_t], and auto-dismantling is [!a_dis?"de":""]activated."
+
+/obj/machinery/pipelayer/proc/reset()
+ on=0
+ return
+
+/obj/machinery/pipelayer/proc/load_metal(var/obj/item/stack/sheet/metal/MM)
+ if(istype(MM) && MM.get_amount())
+ var/cur_amount = metal
+ var/to_load = max(max_metal - round(cur_amount),0)
+ if(to_load)
+ to_load = min(MM.get_amount(), to_load)
+ metal += to_load
+ MM.use(to_load)
+ return to_load
+ else
+ return 0
+ return
+
+/obj/machinery/pipelayer/proc/use_metal(amount)
+ if(!metal || metal