diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
index 20509af301d..72e9848e634 100644
--- a/code/game/machinery/computer/pod.dm
+++ b/code/game/machinery/computer/pod.dm
@@ -310,10 +310,9 @@
spawn_marauder.Add(L)
for(var/obj/effect/landmark/L in world)
if(L.name == "Marauder Exit")
- var/obj/effect/portal/P = new(L.loc)
+ var/obj/effect/portal/P = new(L.loc, pick(spawn_marauder))
P.invisibility = 101//So it is not seen by anyone.
P.failchance = 0//So it has no fail chance when teleporting.
- P.target = pick(spawn_marauder)//Where the marauder will arrive.
spawn_marauder.Remove(P.target)
for(var/obj/machinery/door/poddoor/M in world)
diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm
index 5d7c67d29ee..3f8692e3697 100644
--- a/code/game/machinery/computer/specops_shuttle.dm
+++ b/code/game/machinery/computer/specops_shuttle.dm
@@ -165,10 +165,9 @@ var/specops_shuttle_timeleft = 0
spawn_marauder.Add(L.loc)
for(var/obj/effect/landmark/L in world)
if(L.name == "Marauder Exit")
- var/obj/effect/portal/P = new(L.loc)
+ var/obj/effect/portal/P = new(L.loc, pick(spawn_marauder))
//P.invisibility = 101//So it is not seen by anyone.
P.failchance = 0//So it has no fail chance when teleporting.
- P.target = pick(spawn_marauder)//Where the marauder will arrive.
spawn_marauder.Remove(P.target)
sleep(10)
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index 41b6b99fb87..3ea7afe0b8d 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -429,9 +429,7 @@
return
chassis.use_power(energy_drain)
set_ready_state(0)
- var/obj/effect/portal/P = new /obj/effect/portal(get_turf(target))
- P.target = target_turf
- P.creator = null
+ var/obj/effect/portal/P = new /obj/effect/portal(get_turf(target), target_turf)
P.icon = 'icons/obj/objects.dmi'
P.failchance = 0
P.icon_state = "anom"
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 63ab4f67a02..938e9fcc9fd 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -416,7 +416,7 @@
var/obj/O = obstacle
if(istype(O, /obj/effect/portal)) //derpfix
src.anchored = 0
- O.Crossed(src)
+ O.Bumped(src)
spawn(0)//countering portal teleport spawn(0), hurr
src.anchored = 1
else if(!O.anchored)
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index 7dcfbe425cc..29fec7bce86 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -9,24 +9,18 @@
var/obj/item/target = null
var/creator = null
anchored = 1.0
+ var/precision = 1 // how close to the portal you will teleport. 0 = on the portal, 1 = adjacent
/obj/effect/portal/Bumped(mob/M as mob|obj)
- spawn(0)
- src.teleport(M)
- return
- return
+ src.teleport(M)
-/obj/effect/portal/Crossed(AM as mob|obj)
- spawn(0)
- src.teleport(AM)
- return
- return
-
-/obj/effect/portal/New()
+/obj/effect/portal/New(loc, turf/target, creator)
portals += src
+ src.loc = loc
+ src.target = target
+ src.creator = creator
spawn(300)
qdel(src)
- return
return
/obj/effect/portal/Destroy()
@@ -34,14 +28,16 @@
if(istype(creator, /obj/item/weapon/hand_tele))
var/obj/item/weapon/hand_tele/O = creator
O.active_portals--
+ else if(istype(creator, /obj/item/weapon/gun/energy/wormhole_projector))
+ var/obj/item/weapon/gun/energy/wormhole_projector/P = creator
+ P.portal_destroyed(src)
+ creator = null
return ..()
/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj)
if(istype(M, /obj/effect)) //sparks don't teleport
return
- if (M.anchored&&istype(M, /obj/mecha))
- return
- if (icon_state == "portal1")
+ if(M.anchored&&istype(M, /obj/mecha))
return
if (!( target ))
qdel(src)
@@ -51,5 +47,4 @@
src.icon_state = "portal1"
do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0)
else
- do_teleport(M, target, 1) ///You will appear adjacent to the beacon
-
+ do_teleport(M, target, precision) ///You will appear adjacent to the beacon
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index d079ecd47dd..6fcc67e1e67 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -46,12 +46,12 @@ Frequency:
/obj/item/weapon/locator/Topic(href, href_list)
if(..())
return 1
-
+
var/turf/current_location = get_turf(usr)//What turf is the user on?
if(!current_location ||( current_location.z in config.admin_levels))//If turf was not found or they're on z level 2.
usr << "\The [src] is malfunctioning."
return 1
-
+
if (href_list["refresh"])
temp = "Persistent Signal Locator
"
var/turf/sr = get_turf(src)
@@ -135,9 +135,7 @@ Frequency:
return
var/T = L[t1]
user.show_message("Locked In.", 2)
- var/obj/effect/portal/P = new /obj/effect/portal( get_turf(src) )
- P.target = T
- P.creator = src
+ var/obj/effect/portal/P = new /obj/effect/portal(get_turf(src), T, src)
try_move_adjacent(P)
active_portals++
add_fingerprint(user)
diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm
index 9383a78588c..1de1b266a47 100644
--- a/code/modules/mining/equipment_locker.dm
+++ b/code/modules/mining/equipment_locker.dm
@@ -534,7 +534,6 @@
return
var/chosen_beacon = pick(L)
var/obj/effect/portal/wormhole/jaunt_tunnel/J = new /obj/effect/portal/wormhole/jaunt_tunnel(get_turf(src), chosen_beacon)
- J.target = chosen_beacon
try_move_adjacent(J)
playsound(src,'sound/effects/sparks4.ogg',50,1)
qdel(src)
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 3d765d7e1da..45a89f9e033 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -355,4 +355,69 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
self_recharge = 1
use_external_power = 1
- recharge_time = 5
\ No newline at end of file
+ recharge_time = 5
+
+/obj/item/weapon/gun/energy/wormhole_projector
+ name = "bluespace wormhole projector"
+ desc = "A projector that emits high density quantum-coupled bluespace beams."
+ projectile_type = "/obj/item/projectile/beam/wormhole"
+ charge_cost = 0
+ fire_sound = "sound/weapons/pulse3.ogg"
+ item_state = null
+ icon_state = "wormhole_projector100"
+ modifystate = "wormhole_projector"
+ var/obj/effect/portal/blue
+ var/obj/effect/portal/orange
+
+ var/mode = 0 //0 = blue 1 = orange
+
+
+/obj/item/weapon/gun/energy/wormhole_projector/attack_self(mob/living/user as mob)
+ switch_modes()
+
+/obj/item/weapon/gun/energy/wormhole_projector/proc/switch_modes(mob/living/user as mob)
+ switch(mode)
+ if(0)
+ mode = 1
+ user << "[name] is now set to orange."
+ projectile_type = "/obj/item/projectile/beam/wormhole/orange"
+ modifystate = "wormhole_projector_orange"
+ if(1)
+ mode = 0
+ user << "[name] is now set to blue."
+ projectile_type = "/obj/item/projectile/beam/wormhole"
+ modifystate = "wormhole_projector"
+ update_icon()
+ if(user.hand)
+ user.update_inv_l_hand()
+ else
+ user.update_inv_r_hand()
+
+/obj/item/weapon/gun/energy/wormhole_projector/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)
+ ..()
+ switch_modes(user)
+
+/obj/item/weapon/gun/energy/wormhole_projector/proc/portal_destroyed(obj/effect/portal/P)
+ if(P.icon_state == "portal")
+ blue = null
+ if(orange)
+ orange.target = null
+ else
+ orange = null
+ if(blue)
+ blue.target = null
+
+/obj/item/weapon/gun/energy/wormhole_projector/proc/create_portal(obj/item/projectile/beam/wormhole/W)
+ var/obj/effect/portal/P = new /obj/effect/portal(get_turf(W), null, src)
+ P.precision = 0
+ P.failchance = 0
+ if(W.name == "bluespace beam")
+ qdel(blue)
+ blue = P
+ else
+ qdel(orange)
+ P.icon_state = "portal1"
+ orange = P
+ if(orange && blue)
+ blue.target = get_turf(orange)
+ orange.target = get_turf(blue)
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index a379e6cb61c..b5665a6af1c 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -9,6 +9,7 @@
/obj/item/projectile/energy/electrode
name = "electrode"
icon_state = "spark"
+ color = "#FFFF00"
nodamage = 1
stun = 5
weaken = 5
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index ac9cb8f0ac8..3b8f87ddc39 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -331,3 +331,27 @@ obj/item/projectile/kinetic/New()
/obj/item/projectile/plasma/adv/mech
damage = 10
range = 6
+
+/obj/item/projectile/beam/wormhole
+ name = "bluespace beam"
+ icon_state = "spark"
+ hitsound = "sparks"
+ damage = 3
+ var/obj/item/weapon/gun/energy/wormhole_projector/gun = null
+ color = "#33CCFF"
+
+/obj/item/projectile/beam/wormhole/orange
+ name = "orange bluespace beam"
+ color = "#FF6600"
+
+/obj/item/projectile/beam/wormhole/OnFired()
+ gun = shot_from
+
+/obj/item/projectile/beam/wormhole/on_hit(atom/target)
+ if(ismob(target))
+ var/turf/portal_destination = pick(orange(6, src))
+ do_teleport(target, portal_destination)
+ return ..()
+ if(!gun)
+ qdel(src)
+ gun.create_portal(src)
\ No newline at end of file
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index 5c4ed5c4299..e0e691e8e45 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -60,6 +60,16 @@
locked = 1
category = list("Weapons")
+/datum/design/wormhole_projector
+ name = "Bluespace Wormhole Projector"
+ desc = "A projector that emits high density quantum-coupled bluespace beams."
+ id = "wormholeprojector"
+ req_tech = list("combat" = 6, "materials" = 6, "bluespace" = 4)
+ build_type = PROTOLATHE
+ materials = list(MAT_SILVER = 1000, MAT_METAL = 5000, MAT_DIAMOND = 3000)
+ build_path = /obj/item/weapon/gun/energy/wormhole_projector
+ category = list("Weapons")
+
/datum/design/large_grenade
name = "Large Grenade"
desc = "A grenade that affects a larger area and use larger containers."
@@ -133,7 +143,7 @@
materials = list(MAT_METAL = 2000)
build_path = /obj/item/ammo_box/magazine/smgm9mm
category = list("Weapons")
-
+
/datum/design/mag_smg/ap_mag
name = "Saber Submachine Gun Magazine (9mmAP)"
desc = "A 30-round armour piercing magazine for the Saber submachine gun. Deals slightly less damage but bypasses most armor."
diff --git a/icons/mob/inhands/guns_lefthand.dmi b/icons/mob/inhands/guns_lefthand.dmi
index 77403c2dc9c..1d0f86b5842 100644
Binary files a/icons/mob/inhands/guns_lefthand.dmi and b/icons/mob/inhands/guns_lefthand.dmi differ
diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi
index e339f5b9f9a..f5d84cb5f0e 100644
Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ
diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi
index ee60d654a48..15ea68c087a 100644
Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index 578e722986d..d8a0e56ac53 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi
index 545ec7df5cc..d737faf3b0d 100755
Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ