diff --git a/baystation12.dme b/baystation12.dme
index fd1058c3b44..68d5ab3d3d0 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1101,6 +1101,7 @@
#include "code\modules\projectiles\guns\energy\stun.dm"
#include "code\modules\projectiles\guns\energy\temperature.dm"
#include "code\modules\projectiles\guns\projectile\automatic.dm"
+#include "code\modules\projectiles\guns\projectile\bow.dm"
#include "code\modules\projectiles\guns\projectile\pistol.dm"
#include "code\modules\projectiles\guns\projectile\pneumatic.dm"
#include "code\modules\projectiles\guns\projectile\revolver.dm"
diff --git a/code/modules/projectiles/guns/projectile/bow.dm b/code/modules/projectiles/guns/projectile/bow.dm
new file mode 100644
index 00000000000..a052f198422
--- /dev/null
+++ b/code/modules/projectiles/guns/projectile/bow.dm
@@ -0,0 +1,190 @@
+/obj/item/weapon/arrow
+
+ name = "bolt"
+ desc = "It's got a tip for you - get the point?"
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "bolt"
+ item_state = "bolt"
+ flags = FPRINT | TABLEPASS
+ throwforce = 12
+ w_class = 2.0
+ sharp = 1
+
+/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart..
+ return
+
+/obj/item/weapon/arrow/rod
+
+ name = "metal rod"
+ desc = "Don't cry for me, Orithena."
+ icon_state = "metal-rod"
+
+/obj/item/weapon/arrow/rod/removed(mob/user)
+ if(throwforce == 20) // The rod has been superheated - we don't want it to be useable when removed from the bow.
+ user << "[src] shatters into a scattering of overstressed metal shards as it leaves the crossbow."
+ var/obj/item/weapon/shard/shrapnel/S = new()
+ S.loc = get_turf(src)
+ src.Del()
+
+/obj/item/weapon/crossbow
+
+ name = "powered crossbow"
+ desc = "A 2557AD twist on an old classic. Pick up that can."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "crossbow"
+ item_state = "crossbow-solid"
+ w_class = 4.0
+ flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY
+ slot_flags = SLOT_BELT | SLOT_BACK
+
+ w_class = 3.0
+
+ var/tension = 0 // Current draw on the bow.
+ var/max_tension = 5 // Highest possible tension.
+ var/release_speed = 5 // Speed per unit of tension.
+ var/mob/living/current_user = null // Used to see if the person drawing the bow started drawing it.
+ var/obj/item/weapon/arrow = null // Nocked arrow.
+ var/obj/item/weapon/cell/cell = null // Used for firing special projectiles like rods.
+
+/obj/item/weapon/crossbow/attackby(obj/item/W as obj, mob/user as mob)
+ if(!arrow)
+ if (istype(W,/obj/item/weapon/arrow))
+ user.drop_item()
+ arrow = W
+ arrow.loc = src
+ user.visible_message("[user] slides [arrow] into [src].","You slide [arrow] into [src].")
+ icon_state = "crossbow-nocked"
+ return
+ else if(istype(W,/obj/item/stack/rods))
+ var/obj/item/stack/rods/R = W
+ R.use(1)
+ arrow = new /obj/item/weapon/arrow/rod(src)
+ arrow.loc = src
+ user.visible_message("[user] haphazardly jams [arrow] into [src].","You jam [arrow] into [src].")
+ if(cell)
+ if(cell.charge >= 500)
+ user << "[arrow] plinks and crackles as it begins to glow red-hot."
+ arrow.throwforce = 20
+ arrow.icon_state = "metal-rod-superheated"
+
+ return
+
+ if(istype(W, /obj/item/weapon/cell))
+ if(!cell)
+ user.drop_item()
+ W.loc = src
+ cell = W
+ user << "You jam [cell] into [src] and wire it to the firing coil."
+ if(arrow)
+ if(istype(arrow,/obj/item/weapon/arrow/rod) && cell.charge >= 500)
+ user << "[arrow] plinks and crackles as it begins to glow red-hot."
+ arrow.throwforce = 20
+ arrow.icon_state = "metal-rod-superheated"
+ cell.charge -= 500
+ else
+ user << "[src] already has a cell installed."
+
+ else if(istype(W, /obj/item/weapon/screwdriver))
+ if(cell)
+ var/obj/item/C = cell
+ C.loc = get_turf(user)
+ cell = null
+ user << "You jimmy [cell] out of [src] with [W]."
+ else
+ user << "[src] doesn't have a cell installed."
+
+ else
+ ..()
+
+/obj/item/weapon/crossbow/attack_self(mob/living/user as mob)
+ if(tension)
+ if(arrow)
+ user.visible_message("[user] relaxes the tension on [src]'s string and removes [arrow].","You relax the tension on [src]'s string and remove [arrow].")
+ var/obj/item/weapon/arrow/A = arrow
+ A.loc = get_turf(src)
+ A.removed(user)
+ arrow = null
+ else
+ user.visible_message("[user] relaxes the tension on [src]'s string.","You relax the tension on [src]'s string.")
+ tension = 0
+ icon_state = "crossbow"
+ else
+ draw(user)
+
+/obj/item/weapon/crossbow/proc/draw(var/mob/user as mob)
+
+ if(!arrow)
+ user << "You don't have anything nocked to [src]."
+ return
+
+ if(user.restrained())
+ return
+
+ current_user = user
+
+ user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].")
+ tension = 1
+ spawn(25) increase_tension(user)
+
+/obj/item/weapon/crossbow/proc/increase_tension(var/mob/user as mob)
+
+ if(!arrow || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed.
+ return
+
+ tension++
+ icon_state = "crossbow-drawn"
+
+ if(tension>=max_tension)
+ tension = max_tension
+ usr << "[src] clunks as you draw the string to its maximum tension!"
+ else
+ user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!")
+ spawn(25) increase_tension(user)
+
+/obj/item/weapon/crossbow/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
+
+ if (istype(target, /obj/item/weapon/storage/backpack ))
+ src.dropped()
+ return
+
+ else if (target.loc == user.loc)
+ return
+
+ else if (locate (/obj/structure/table, src.loc))
+ return
+
+ else if(target == user)
+ return
+
+ if (!arrow)
+ user << "You have no arrow nocked to [src]!"
+ return 0
+ else
+ spawn(0) Fire(target,user,params)
+
+/obj/item/weapon/crossbow/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
+
+ add_fingerprint(user)
+
+ var/turf/curloc = get_turf(user)
+ var/turf/targloc = get_turf(target)
+ if (!istype(targloc) || !istype(curloc))
+ return
+
+ user.visible_message("[user] releases [src] and sends [arrow] streaking toward [target]!","You release [src] and send [arrow] streaking toward [target]!")
+
+ var/obj/item/weapon/arrow/A = arrow
+ A.loc = get_turf(user)
+ A.throw_at(target,10,tension*release_speed)
+ arrow = null
+ tension = 0
+ icon_state = "crossbow"
+
+/obj/item/weapon/crossbow/dropped(mob/user)
+ if(arrow)
+ var/obj/item/weapon/arrow/A = arrow
+ A.loc = get_turf(src)
+ A.removed(user)
+ arrow = null
+ tension = 0
+ icon_state = "crossbow"
\ No newline at end of file
diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi
index 318cde63593..f0406239c96 100644
Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ
diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi
index 5829ad8e5f0..954ddb81114 100644
Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ
diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi
index 56fa5229749..ecce9fa6aae 100644
Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ