diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index c40c5db48c..fb173e31c3 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -425,6 +425,24 @@
origin_tech = list(TECH_POWER = 1)
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 50)
+ var/charge = 0
+ var/max_charge = 1000
+
+/obj/item/weapon/stock_parts/capacitor/New()
+ . = ..()
+ max_charge *= rating
+
+/obj/item/weapon/stock_parts/capacitor/proc/charge(var/amount)
+ charge += amount
+ if(charge > max_charge)
+ charge = max_charge
+
+/obj/item/weapon/stock_parts/capacitor/proc/use(var/amount)
+ if(charge)
+ charge -= amount
+ if(charge < 0)
+ charge = 0
+
/obj/item/weapon/stock_parts/scanning_module
name = "scanning module"
desc = "A compact, high resolution scanning module used in the construction of certain devices."
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index e21c509c15..d79f584e2f 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -17,6 +17,7 @@
matter = list(DEFAULT_WALL_MATERIAL = 50000)
var/datum/effect/effect/system/spark_spread/spark_system
var/stored_matter = 0
+ var/max_stored_matter = 30
var/working = 0
var/mode = 1
var/list/modes = list("Floor & Walls","Airlock","Deconstruct")
@@ -32,7 +33,7 @@
/obj/item/weapon/rcd/examine()
..()
if(src.type == /obj/item/weapon/rcd && loc == usr)
- usr << "It currently holds [stored_matter]/30 matter-units."
+ usr << "It currently holds [stored_matter]/[max_stored_matter] matter-units."
/obj/item/weapon/rcd/New()
..()
@@ -48,14 +49,15 @@
/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/rcd_ammo))
- if((stored_matter + 10) > 30)
- user << "The RCD can't hold any more matter-units."
+ var/obj/item/weapon/rcd_ammo/cartridge = W
+ if((stored_matter + cartridge.remaining) > max_stored_matter)
+ to_chat(user, "The RCD can't hold that many additional matter-units.")
return
+ stored_matter += cartridge.remaining
user.drop_from_inventory(W)
qdel(W)
- stored_matter += 10
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
- user << "The RCD now holds [stored_matter]/30 matter-units."
+ to_chat(user, "The RCD now holds [stored_matter]/[max_stored_matter] matter-units.")
return
..()
@@ -164,6 +166,14 @@
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_MATERIAL = 2)
matter = list(DEFAULT_WALL_MATERIAL = 30000,"glass" = 15000)
+ var/remaining = 10
+
+/obj/item/weapon/rcd_ammo/large
+ name = "high-capacity matter cartridge"
+ desc = "Do not ingest."
+ matter = list(DEFAULT_WALL_MATERIAL = 45000,"glass" = 22500)
+ remaining = 30
+ origin_tech = list(TECH_MATERIAL = 4)
/obj/item/weapon/rcd/borg
canRwall = 1
diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm
index 99abbe2e12..3e3099bbbc 100644
--- a/code/modules/materials/material_recipes.dm
+++ b/code/modules/materials/material_recipes.dm
@@ -135,6 +135,7 @@
recipes += new/datum/stack_recipe("book shelf", /obj/structure/bookcase, 5, time = 15, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("noticeboard frame", /obj/item/frame/noticeboard, 4, time = 5, one_per_turf = 0, on_floor = 1)
recipes += new/datum/stack_recipe("wooden bucket", /obj/item/weapon/reagent_containers/glass/bucket/wood, 2, time = 4, one_per_turf = 0, on_floor = 0)
+ recipes += new/datum/stack_recipe("coilgun stock", /obj/item/weapon/coilgun_assembly, 5)
/material/cardboard/generate_recipes()
..()
diff --git a/code/modules/projectiles/ammunition/magnetic.dm b/code/modules/projectiles/ammunition/magnetic.dm
new file mode 100644
index 0000000000..fc299adf0b
--- /dev/null
+++ b/code/modules/projectiles/ammunition/magnetic.dm
@@ -0,0 +1,13 @@
+/obj/item/weapon/magnetic_ammo
+ name = "flechette magazine"
+ desc = "A magazine containing steel flechettes."
+ icon = 'icons/obj/ammo.dmi'
+ icon_state = "5.56"
+ w_class = ITEMSIZE_SMALL
+ matter = list(DEFAULT_WALL_MATERIAL = 1800)
+ origin_tech = list(TECH_COMBAT = 1)
+ var/remaining = 9
+
+/obj/item/weapon/magnetic_ammo/examine(mob/user)
+ . = ..()
+ to_chat(user, "There [(remaining == 1)? "is" : "are"] [remaining] flechette\s left!")
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm
new file mode 100644
index 0000000000..130f4410df
--- /dev/null
+++ b/code/modules/projectiles/guns/magnetic/magnetic.dm
@@ -0,0 +1,195 @@
+/obj/item/weapon/gun/magnetic
+ name = "improvised coilgun"
+ desc = "A coilgun hastily thrown together out of a basic frame and advanced power storage components. Is it safe for it to be duct-taped together like that?"
+ icon_state = "coilgun"
+ item_state = "coilgun"
+ icon = 'icons/obj/railgun.dmi'
+// one_hand_penalty = 1
+ origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_ILLEGAL = 2, TECH_MAGNET = 4)
+ w_class = ITEMSIZE_LARGE
+
+ var/obj/item/weapon/cell/cell // Currently installed powercell.
+ var/obj/item/weapon/stock_parts/capacitor/capacitor // Installed capacitor. Higher rating == faster charge between shots.
+ var/removable_components = TRUE // Whether or not the gun can be dismantled.
+ var/gun_unreliable = 15 // Percentage chance of detonating in your hands.
+
+ var/obj/item/loaded // Currently loaded object, for retrieval/unloading.
+ var/load_type = /obj/item/stack/rods // Type of stack to load with.
+ var/projectile_type = /obj/item/projectile/bullet/magnetic // Actual fire type, since this isn't throw_at rod launcher.
+
+ var/power_cost = 950 // Cost per fire, should consume almost an entire basic cell.
+ var/power_per_tick // Capacitor charge per process(). Updated based on capacitor rating.
+
+ fire_sound = 'sound/weapons/railgun.ogg'
+
+/obj/item/weapon/gun/magnetic/New()
+ processing_objects.Add(src)
+ if(capacitor)
+ power_per_tick = (power_cost*0.15) * capacitor.rating
+ update_icon()
+ . = ..()
+
+/obj/item/weapon/gun/magnetic/Destroy()
+ processing_objects.Remove(src)
+ qdel_null(cell)
+ qdel_null(loaded)
+ qdel_null(capacitor)
+ . = ..()
+
+/obj/item/weapon/gun/magnetic/process()
+ if(capacitor)
+ if(cell)
+ if(capacitor.charge < capacitor.max_charge && cell.checked_use(power_per_tick))
+ capacitor.charge(power_per_tick)
+ else
+ capacitor.use(capacitor.charge * 0.05)
+ update_icon()
+
+/obj/item/weapon/gun/magnetic/update_icon()
+ var/list/overlays_to_add = list()
+ if(removable_components)
+ if(cell)
+ overlays_to_add += image(icon, "[icon_state]_cell")
+ if(capacitor)
+ overlays_to_add += image(icon, "[icon_state]_capacitor")
+ if(!cell || !capacitor)
+ overlays_to_add += image(icon, "[icon_state]_red")
+ else if(capacitor.charge < power_cost)
+ overlays_to_add += image(icon, "[icon_state]_amber")
+ else
+ overlays_to_add += image(icon, "[icon_state]_green")
+ if(loaded)
+ overlays_to_add += image(icon, "[icon_state]_loaded")
+
+ overlays = overlays_to_add
+ ..()
+
+/obj/item/weapon/gun/magnetic/proc/show_ammo(var/mob/user)
+ if(loaded)
+ to_chat(user, "It has \a [loaded] loaded.")
+
+/obj/item/weapon/gun/magnetic/examine(var/mob/user)
+ . = ..(user, 2)
+ if(.)
+ show_ammo(user)
+
+ if(cell)
+ to_chat(user, "The installed [cell.name] has a charge level of [round((cell.charge/cell.maxcharge)*100)]%.")
+ if(capacitor)
+ to_chat(user, "The installed [capacitor.name] has a charge level of [round((capacitor.charge/capacitor.max_charge)*100)]%.")
+
+ if(!cell || !capacitor)
+ to_chat(user, "The capacitor charge indicator is blinking red. Maybe you should check the cell or capacitor.")
+ else
+ if(capacitor.charge < power_cost)
+ to_chat(user, "The capacitor charge indicator is amber.")
+ else
+ to_chat(user, "The capacitor charge indicator is green.")
+ return TRUE
+
+/obj/item/weapon/gun/magnetic/attackby(var/obj/item/thing, var/mob/user)
+
+ if(removable_components)
+ if(istype(thing, /obj/item/weapon/cell))
+ if(cell)
+ to_chat(user, "\The [src] already has \a [cell] installed.")
+ return
+ cell = thing
+ user.drop_from_inventory(cell)
+ cell.forceMove(src)
+ playsound(loc, 'sound/machines/click.ogg', 10, 1)
+ user.visible_message("\The [user] slots \the [cell] into \the [src].")
+ update_icon()
+ return
+
+ if(isscrewdriver(thing))
+ if(!capacitor)
+ to_chat(user, "\The [src] has no capacitor installed.")
+ return
+ capacitor.forceMove(get_turf(src))
+ user.put_in_hands(capacitor)
+ user.visible_message("\The [user] unscrews \the [capacitor] from \the [src].")
+ playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ capacitor = null
+ update_icon()
+ return
+
+ if(istype(thing, /obj/item/weapon/stock_parts/capacitor))
+ if(capacitor)
+ to_chat(user, "\The [src] already has \a [capacitor] installed.")
+ return
+ capacitor = thing
+ user.drop_from_inventory(capacitor)
+ capacitor.forceMove(src)
+ playsound(loc, 'sound/machines/click.ogg', 10, 1)
+ power_per_tick = (power_cost*0.15) * capacitor.rating
+ user.visible_message("\The [user] slots \the [capacitor] into \the [src].")
+ update_icon()
+ return
+
+ if(istype(thing, load_type))
+
+ if(loaded)
+ to_chat(user, "\The [src] already has \a [loaded] loaded.")
+ return
+
+ // This is not strictly necessary for the magnetic gun but something using
+ // specific ammo types may exist down the track.
+ var/obj/item/stack/ammo = thing
+ if(!istype(ammo))
+ loaded = thing
+ user.drop_from_inventory(thing)
+ thing.forceMove(src)
+ else
+ loaded = new load_type(src, 1)
+ ammo.use(1)
+
+ user.visible_message("\The [user] loads \the [src] with \the [loaded].")
+ playsound(loc, 'sound/weapons/flipblade.ogg', 50, 1)
+ update_icon()
+ return
+ . = ..()
+
+/obj/item/weapon/gun/magnetic/attack_hand(var/mob/user)
+ if(user.get_inactive_hand() == src)
+ var/obj/item/removing
+
+ if(loaded)
+ removing = loaded
+ loaded = null
+ else if(cell && removable_components)
+ removing = cell
+ cell = null
+
+ if(removing)
+ removing.forceMove(get_turf(src))
+ user.put_in_hands(removing)
+ user.visible_message("\The [user] removes \the [removing] from \the [src].")
+ playsound(loc, 'sound/machines/click.ogg', 10, 1)
+ update_icon()
+ return
+ . = ..()
+
+/obj/item/weapon/gun/magnetic/proc/check_ammo()
+ return loaded
+
+/obj/item/weapon/gun/magnetic/proc/use_ammo()
+ qdel(loaded)
+ loaded = null
+
+/obj/item/weapon/gun/magnetic/consume_next_projectile()
+
+ if(!check_ammo() || !capacitor || capacitor.charge < power_cost)
+ return
+
+ use_ammo()
+ capacitor.use(power_cost)
+ update_icon()
+
+ if(gun_unreliable && prob(gun_unreliable))
+ spawn(3) // So that it will still fire - considered modifying Fire() to return a value but burst fire makes that annoying.
+ visible_message("\The [src] explodes with the force of the shot!")
+ explosion(get_turf(src), -1, 0, 2)
+ qdel(src)
+
+ return new projectile_type(src)
diff --git a/code/modules/projectiles/guns/magnetic/magnetic_construction.dm b/code/modules/projectiles/guns/magnetic/magnetic_construction.dm
new file mode 100644
index 0000000000..0c3647458b
--- /dev/null
+++ b/code/modules/projectiles/guns/magnetic/magnetic_construction.dm
@@ -0,0 +1,101 @@
+// We really need some datums for this.
+/obj/item/weapon/coilgun_assembly
+ name = "coilgun stock"
+ desc = "It might be a coilgun, someday."
+ icon = 'icons/obj/coilgun.dmi'
+ icon_state = "coilgun_construction_1"
+
+ var/construction_stage = 1
+
+/obj/item/weapon/coilgun_assembly/attackby(var/obj/item/thing, var/mob/user)
+
+ if(istype(thing, /obj/item/stack/material) && construction_stage == 1)
+ var/obj/item/stack/material/reinforcing = thing
+ var/material/reinforcing_with = reinforcing.get_material()
+ if(reinforcing_with.name == DEFAULT_WALL_MATERIAL) // Steel
+ if(reinforcing.get_amount() < 5)
+ to_chat(user, "You need at least 5 [reinforcing.singular_name]\s for this task.")
+ return
+ reinforcing.use(5)
+ user.visible_message("\The [user] shapes some steel sheets around \the [src] to form a body.")
+ increment_construction_stage()
+ return
+
+ if(istype(thing, /obj/item/weapon/tape_roll) && construction_stage == 2)
+ user.visible_message("\The [user] secures \the [src] together with \the [thing].")
+ increment_construction_stage()
+ return
+
+ if(istype(thing, /obj/item/pipe) && construction_stage == 3)
+ user.drop_from_inventory(thing)
+ qdel(thing)
+ user.visible_message("\The [user] jams \the [thing] into \the [src].")
+ increment_construction_stage()
+ return
+
+ if(istype(thing, /obj/item/weapon/weldingtool) && construction_stage == 4)
+ var/obj/item/weapon/weldingtool/welder = thing
+
+ if(!welder.isOn())
+ to_chat(user, "Turn it on first!")
+ return
+
+ if(!welder.remove_fuel(0,user))
+ to_chat(user, "You need more fuel!")
+ return
+
+ user.visible_message("\The [user] welds the barrel of \the [src] into place.")
+ playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1)
+ increment_construction_stage()
+ return
+
+ if(istype(thing, /obj/item/stack/cable_coil) && construction_stage == 5)
+ var/obj/item/stack/cable_coil/cable = thing
+ if(cable.get_amount() < 5)
+ to_chat(user, "You need at least 5 lengths of cable for this task.")
+ return
+ cable.use(5)
+ user.visible_message("\The [user] wires \the [src].")
+ increment_construction_stage()
+ return
+
+ if(istype(thing, /obj/item/weapon/smes_coil) && construction_stage >= 6 && construction_stage <= 8)
+ user.visible_message("\The [user] installs \a [thing] into \the [src].")
+ user.drop_from_inventory(thing)
+ qdel(thing)
+ increment_construction_stage()
+ return
+
+ if(isscrewdriver(thing) && construction_stage >= 9)
+ user.visible_message("\The [user] secures \the [src] and finishes it off.")
+ playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ var/obj/item/weapon/gun/magnetic/coilgun = new(loc)
+ var/put_in_hands
+ var/mob/M = src.loc
+ if(istype(M))
+ put_in_hands = M == user
+ M.drop_from_inventory(src)
+ if(put_in_hands)
+ user.put_in_hands(coilgun)
+ qdel(src)
+ return
+
+ return ..()
+
+/obj/item/weapon/coilgun_assembly/proc/increment_construction_stage()
+ if(construction_stage < 9)
+ construction_stage++
+ icon_state = "coilgun_construction_[construction_stage]"
+
+/obj/item/weapon/coilgun_assembly/examine(var/mob/user)
+ . = ..(user,2)
+ if(.)
+ switch(construction_stage)
+ if(2) to_chat(user, "It has a metal frame loosely shaped around the stock.")
+ if(3) to_chat(user, "It has a metal frame duct-taped to the stock.")
+ if(4) to_chat(user, "It has a length of pipe attached to the body.")
+ if(4) to_chat(user, "It has a length of pipe welded to the body.")
+ if(6) to_chat(user, "It has a cable mount and capacitor jack wired to the frame.")
+ if(7) to_chat(user, "It has a single superconducting coil threaded onto the barrel.")
+ if(8) to_chat(user, "It has a pair of superconducting coils threaded onto the barrel.")
+ if(9) to_chat(user, "It has three superconducting coils attached to the body, waiting to be secured.")
diff --git a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm
new file mode 100644
index 0000000000..d731512bfa
--- /dev/null
+++ b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm
@@ -0,0 +1,104 @@
+/obj/item/weapon/gun/magnetic/railgun
+ name = "railgun"
+ desc = "The Mars Military Industries MI-76 Thunderclap. A man-portable mass driver for squad support anti-armour and destruction of fortifications and emplacements."
+ gun_unreliable = 0
+ icon_state = "railgun"
+ removable_components = FALSE
+ load_type = /obj/item/weapon/rcd_ammo
+ origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_MAGNET = 4)
+ projectile_type = /obj/item/projectile/bullet/magnetic/slug
+ power_cost = 300
+ w_class = ITEMSIZE_HUGE
+ slot_flags = SLOT_BELT
+ loaded = /obj/item/weapon/rcd_ammo/large
+
+ var/initial_cell_type = /obj/item/weapon/cell/hyper
+ var/initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/adv
+ var/slowdown_held = 2
+ var/slowdown_worn = 1
+
+/obj/item/weapon/gun/magnetic/railgun/New()
+ capacitor = new initial_capacitor_type(src)
+ capacitor.charge = capacitor.max_charge
+
+ cell = new initial_cell_type(src)
+ if (ispath(loaded))
+ loaded = new loaded
+ . = ..()
+
+// Not going to check type repeatedly, if you code or varedit
+// load_type and get runtime errors, don't come crying to me.
+/obj/item/weapon/gun/magnetic/railgun/show_ammo(var/mob/user)
+ var/obj/item/weapon/rcd_ammo/ammo = loaded
+ if (ammo)
+ to_chat(user, "There are [ammo.remaining] shot\s remaining in \the [loaded].")
+ else
+ to_chat(user, "There is nothing loaded.")
+
+/obj/item/weapon/gun/magnetic/railgun/check_ammo()
+ var/obj/item/weapon/rcd_ammo/ammo = loaded
+ return ammo && ammo.remaining
+
+/obj/item/weapon/gun/magnetic/railgun/use_ammo()
+ var/obj/item/weapon/rcd_ammo/ammo = loaded
+ ammo.remaining--
+ if(ammo.remaining <= 0)
+ spawn(3)
+ playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 1)
+ out_of_ammo()
+
+/obj/item/weapon/gun/magnetic/railgun/proc/out_of_ammo()
+ qdel(loaded)
+ loaded = null
+ visible_message("\The [src] beeps and ejects its empty cartridge.")
+
+/obj/item/weapon/gun/magnetic/railgun/automatic // Adminspawn only, this shit is absurd.
+ name = "\improper RHR accelerator"
+ desc = "The Mars Military Industries MI-227 Meteor. Originally a vehicle-mounted turret weapon for heavy anti-vehicular and anti-structural fire, the fact that it was made man-portable is mindboggling in itself."
+ icon_state = "heavy_railgun"
+
+ initial_cell_type = /obj/item/weapon/cell/infinite
+ initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/super
+
+ slowdown_held = 3
+ slowdown_worn = 2
+
+ slot_flags = SLOT_BACK
+ w_class = ITEMSIZE_NO_CONTAINER
+
+ firemodes = list(
+ list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_hand_penalty=1, burst_accuracy=null, dispersion=null),
+ list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_hand_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
+ list(mode_name="long bursts", burst=6, fire_delay=null, move_delay=10, one_hand_penalty=2, burst_accuracy=list(0,-1,-1,-1,-2), dispersion=list(0.6, 0.6, 1.0, 1.0, 1.2)),
+ )
+
+/obj/item/weapon/gun/magnetic/railgun/automatic/examine(var/mob/user)
+ . = ..(user,1)
+ if(.)
+ to_chat(user, "Someone has scratched Ultima Ratio Regum onto the side of the barrel.")
+
+/obj/item/weapon/gun/magnetic/railgun/flechette
+ name = "flechette gun"
+ desc = "The MI-12 Skadi is a burst fire capable railgun that fires flechette rounds at high velocity. Deadly against armour, but much less effective against soft targets."
+ icon_state = "flechette_gun"
+ item_state = "z8carbine"
+ initial_cell_type = /obj/item/weapon/cell/hyper
+ initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/adv
+ slot_flags = SLOT_BACK
+ slowdown_held = 0
+ slowdown_worn = 0
+ power_cost = 100
+ load_type = /obj/item/weapon/magnetic_ammo
+ projectile_type = /obj/item/projectile/bullet/magnetic/flechette
+ loaded = /obj/item/weapon/magnetic_ammo
+ fire_sound = 'sound/weapons/rapidslice.ogg'
+
+ firemodes = list(
+ list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_hand_penalty=1, burst_accuracy=null, dispersion=null),
+ list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_hand_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
+ )
+
+/obj/item/weapon/gun/magnetic/railgun/flechette/out_of_ammo()
+ audible_message("\The [src] beeps to indicate the magazine is empty.")
+ playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
+ ..()
diff --git a/code/modules/projectiles/projectile/magnetic.dm b/code/modules/projectiles/projectile/magnetic.dm
new file mode 100644
index 0000000000..35f98833ef
--- /dev/null
+++ b/code/modules/projectiles/projectile/magnetic.dm
@@ -0,0 +1,21 @@
+// Rod for railguns. Slightly less nasty than the sniper round.
+/obj/item/projectile/bullet/magnetic
+ name = "rod"
+ icon_state = "rod"
+ damage = 65
+ stun = 1
+ weaken = 1
+ penetrating = 5
+ armor_penetration = 70
+
+/obj/item/projectile/bullet/magnetic/slug
+ name = "slug"
+ icon_state = "gauss_silenced"
+ damage = 75
+ armor_penetration = 90
+
+/obj/item/projectile/bullet/magnetic/flechette
+ name = "flechette"
+ icon_state = "flechette"
+ damage = 20
+ armor_penetration = 100
\ No newline at end of file
diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi
index 7b2b705c94..180f51236a 100644
Binary files a/icons/mob/items/lefthand_guns.dmi and b/icons/mob/items/lefthand_guns.dmi differ
diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi
index 7c05fbd61d..4fcc8b6b8d 100644
Binary files a/icons/mob/items/righthand_guns.dmi and b/icons/mob/items/righthand_guns.dmi differ
diff --git a/icons/obj/coilgun.dmi b/icons/obj/coilgun.dmi
new file mode 100644
index 0000000000..238bbd9a3d
Binary files /dev/null and b/icons/obj/coilgun.dmi differ
diff --git a/icons/obj/railgun.dmi b/icons/obj/railgun.dmi
new file mode 100644
index 0000000000..0b00e7a156
Binary files /dev/null and b/icons/obj/railgun.dmi differ
diff --git a/polaris.dme b/polaris.dme
index 020ac0f25a..a773f2c0c1 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -1942,6 +1942,7 @@
#include "code\modules\projectiles\gun.dm"
#include "code\modules\projectiles\projectile.dm"
#include "code\modules\projectiles\ammunition\magazines.dm"
+#include "code\modules\projectiles\ammunition\magnetic.dm"
#include "code\modules\projectiles\ammunition\rounds.dm"
#include "code\modules\projectiles\guns\energy.dm"
#include "code\modules\projectiles\guns\launcher.dm"
@@ -1958,6 +1959,9 @@
#include "code\modules\projectiles\guns\launcher\pneumatic.dm"
#include "code\modules\projectiles\guns\launcher\rocket.dm"
#include "code\modules\projectiles\guns\launcher\syringe_gun.dm"
+#include "code\modules\projectiles\guns\magnetic\magnetic.dm"
+#include "code\modules\projectiles\guns\magnetic\magnetic_construction.dm"
+#include "code\modules\projectiles\guns\magnetic\magnetic_railgun.dm"
#include "code\modules\projectiles\guns\projectile\automatic.dm"
#include "code\modules\projectiles\guns\projectile\boltaction.dm"
#include "code\modules\projectiles\guns\projectile\contender.dm"
@@ -1974,6 +1978,7 @@
#include "code\modules\projectiles\projectile\change.dm"
#include "code\modules\projectiles\projectile\energy.dm"
#include "code\modules\projectiles\projectile\force.dm"
+#include "code\modules\projectiles\projectile\magnetic.dm"
#include "code\modules\projectiles\projectile\special.dm"
#include "code\modules\projectiles\targeting\targeting_client.dm"
#include "code\modules\projectiles\targeting\targeting_gun.dm"
diff --git a/sound/weapons/railgun.ogg b/sound/weapons/railgun.ogg
new file mode 100644
index 0000000000..0b939fd9a6
Binary files /dev/null and b/sound/weapons/railgun.ogg differ