diff --git a/baystation12.dme b/baystation12.dme
index 69ba8dd3a78..c20a1002eba 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1242,6 +1242,7 @@
#include "code\modules\surgery\ribcage.dm"
#include "code\modules\surgery\robolimbs.dm"
#include "code\modules\surgery\surgery.dm"
+#include "code\modules\telesci\bscrystal.dm"
#include "code\modules\telesci\gps.dm"
#include "code\modules\telesci\telepad.dm"
#include "code\modules\telesci\telesci_computer.dm"
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 0b535a44c39..8da220bf671 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -327,3 +327,41 @@ proc/isInSight(var/atom/A, var/atom/B)
spawn(delay)
for(var/client/C in group)
C.screen -= O
+
+datum/projectile_data
+ var/src_x
+ var/src_y
+ var/time
+ var/distance
+ var/power_x
+ var/power_y
+ var/dest_x
+ var/dest_y
+
+/datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \
+ var/power_x, var/power_y, var/dest_x, var/dest_y)
+ src.src_x = src_x
+ src.src_y = src_y
+ src.time = time
+ src.distance = distance
+ src.power_x = power_x
+ src.power_y = power_y
+ src.dest_x = dest_x
+ src.dest_y = dest_y
+
+/proc/projectile_trajectory(var/src_x, var/src_y, var/rotation, var/angle, var/power)
+
+ // returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle],
+ // rotated at [rotation] and with the power of [power]
+ // Thanks to VistaPOWA for this function
+
+ var/power_x = power * cos(angle)
+ var/power_y = power * sin(angle)
+ var/time = 2* power_y / 10 //10 = g
+
+ var/distance = time * power_x
+
+ var/dest_x = src_x + distance*sin(rotation);
+ var/dest_y = src_y + distance*cos(rotation);
+
+ return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm
index ab8b95e1116..40e27519cca 100644
--- a/code/modules/research/designs.dm
+++ b/code/modules/research/designs.dm
@@ -1611,6 +1611,16 @@ datum/design/bag_holding
reliability_base = 80
build_path = "/obj/item/weapon/storage/backpack/holding"
+datum/design/bluespace_crystal
+ name = "Artificial Bluespace Crystal"
+ desc = "A small blue crystal with mystical properties."
+ id = "bluespace_crystal"
+ req_tech = list("bluespace" = 5, "materials" = 7)
+ build_type = PROTOLATHE
+ materials = list("$gold" = 1500, "$diamond" = 3000, "$plasma" = 1500)
+ reliability_base = 100
+ build_path = "/obj/item/bluespace_crystal/artificial"
+
/////////////////////////////////////////
/////////////////HUDs////////////////////
/////////////////////////////////////////
@@ -1841,4 +1851,4 @@ datum/design/cart_traitor
req_tech = list("syndicate" = 2, "powerstorage" = 3)
build_type = PROTOLATHE
materials = list("$metal" = 50, "$glass" = 50)
- build_path = "/obj/item/weapon/cartridge/syndicate"
\ No newline at end of file
+ build_path = "/obj/item/weapon/cartridge/syndicate"
diff --git a/code/modules/telesci/bscrystal.dm b/code/modules/telesci/bscrystal.dm
new file mode 100644
index 00000000000..d9e968f4daf
--- /dev/null
+++ b/code/modules/telesci/bscrystal.dm
@@ -0,0 +1,38 @@
+// Bluespace crystals, used in telescience and when crushed it will blink you to a random turf.
+
+/obj/item/bluespace_crystal
+ name = "bluespace crystal"
+ desc = "A glowing bluespace crystal, not much is known about how they work. It looks very delicate."
+ icon = 'icons/obj/telescience.dmi'
+ icon_state = "bluespace_crystal"
+ w_class = 1
+ origin_tech = "bluespace=4;materials=3"
+ var/blink_range = 8 // The teleport range when crushed/thrown at someone.
+
+/obj/item/bluespace_crystal/New()
+ ..()
+ pixel_x = rand(-5, 5)
+ pixel_y = rand(-5, 5)
+
+/obj/item/bluespace_crystal/attack_self(var/mob/user)
+ blink_mob(user)
+ user.drop_item()
+ user.visible_message("[user] crushes the [src]!")
+ del(src)
+
+/obj/item/bluespace_crystal/proc/blink_mob(var/mob/living/L)
+ do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg')
+
+/obj/item/bluespace_crystal/throw_impact(atom/hit_atom)
+ ..()
+ if(isliving(hit_atom))
+ blink_mob(hit_atom)
+ del(src)
+
+// Artifical bluespace crystal, doesn't give you much research.
+
+/obj/item/bluespace_crystal/artificial
+ name = "artificial bluespace crystal"
+ desc = "An artificially made bluespace crystal, it looks delicate."
+ origin_tech = "bluespace=2"
+ blink_range = 4 // Not as good as the organic stuff!
\ No newline at end of file
diff --git a/code/modules/telesci/gps.dm b/code/modules/telesci/gps.dm
index 79897c7e6ea..3850d439d21 100644
--- a/code/modules/telesci/gps.dm
+++ b/code/modules/telesci/gps.dm
@@ -1,5 +1,6 @@
+var/list/GPS_list = list()
/obj/item/device/gps
- name = "Global Positioning System"
+ name = "global positioning system"
desc = "Helping lost spacemen find their way through the planets since 2016."
icon = 'icons/obj/telescience.dmi'
icon_state = "gps-c"
@@ -11,9 +12,15 @@
var/emped = 0
/obj/item/device/gps/New()
- name = "Global Positioning System ([gpstag])"
+ ..()
+ GPS_list.Add(src)
+ name = "global positioning system ([gpstag])"
overlays += "working"
+/obj/item/device/gps/Del()
+ GPS_list.Remove(src)
+ ..()
+
/obj/item/device/gps/emp_act(severity)
emped = 1
overlays -= "working"
@@ -24,6 +31,7 @@
overlays += "working"
/obj/item/device/gps/attack_self(mob/user as mob)
+
var/obj/item/device/gps/t = ""
if(emped)
t += "ERROR"
@@ -31,7 +39,7 @@
t += "
Set Tag "
t += "
Tag: [gpstag]"
- for(var/obj/item/device/gps/G in world)
+ for(var/obj/item/device/gps/G in GPS_list)
var/turf/pos = get_turf(G)
var/area/gps_area = get_area(G)
var/tracked_gpstag = G.gpstag
@@ -46,16 +54,14 @@
popup.open()
/obj/item/device/gps/Topic(href, href_list)
+ ..()
if(href_list["tag"] )
var/a = input("Please enter desired tag.", name, gpstag) as text
- a = copytext(sanitize(a), 1, 20)
- if(length(a) != 4)
- usr << "\blue The tag must be four letters long!"
- return
- else
+ a = uppertext(copytext(sanitize(a), 1, 5))
+ if(src.loc == usr)
gpstag = a
- name = "Global Positioning System ([gpstag])"
- return
+ name = "global positioning system ([gpstag])"
+ attack_self(usr)
/obj/item/device/gps/science
icon_state = "gps-s"
diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm
index 1ebc1a3572e..c54d079afde 100644
--- a/code/modules/telesci/telepad.dm
+++ b/code/modules/telesci/telepad.dm
@@ -8,10 +8,6 @@
use_power = 1
idle_power_usage = 200
active_power_usage = 5000
-/obj/machinery/telepad/New()
- ..()
-/obj/machinery/telepad/Del()
- ..()
//CARGO TELEPAD//
/obj/machinery/telepad_cargo
name = "cargo telepad"
@@ -23,39 +19,35 @@
idle_power_usage = 20
active_power_usage = 500
var/stage = 0
-/obj/machinery/telepad_cargo/New()
- ..()
-/obj/machinery/telepad_cargo/Del()
- ..()
/obj/machinery/telepad_cargo/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
anchored = 0
playsound(src, 'sound/items/Ratchet.ogg', 50, 1)
if(anchored)
anchored = 0
- user << "\blue The [src] can now be moved."
+ user << " The [src] can now be moved."
else if(!anchored)
anchored = 1
- user << "\blue The [src] is now secured."
+ user << " The [src] is now secured."
if(istype(W, /obj/item/weapon/screwdriver))
if(stage == 0)
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
- user << "\blue You unscrew the telepad's tracking beacon."
+ user << " You unscrew the telepad's tracking beacon."
stage = 1
else if(stage == 1)
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
- user << "\blue You screw in the telepad's tracking beacon."
+ user << " You screw in the telepad's tracking beacon."
stage = 0
if(istype(W, /obj/item/weapon/weldingtool) && stage == 1)
playsound(src, 'sound/items/Welder.ogg', 50, 1)
- user << "\blue You disassemble the telepad."
+ user << " You disassemble the telepad."
new /obj/item/stack/sheet/metal(get_turf(src))
new /obj/item/stack/sheet/glass(get_turf(src))
del(src)
///TELEPAD CALLER///
/obj/item/device/telepad_beacon
- name = "Telepad Beacon"
+ name = "telepad beacon"
desc = "Use to warp in a cargo telepad."
icon = 'icons/obj/radio.dmi'
icon_state = "beacon"
@@ -64,7 +56,7 @@
/obj/item/device/telepad_beacon/attack_self(mob/user as mob)
if(user)
- user << "\blue Locked In"
+ user << " Locked In"
new /obj/machinery/telepad_cargo(user.loc)
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
del(src)
@@ -76,9 +68,6 @@
desc = "Use this to send crates and closets to cargo telepads."
icon = 'icons/obj/telescience.dmi'
icon_state = "rcs"
- opacity = 0
- density = 0
- anchored = 0.0
flags = FPRINT | TABLEPASS| CONDUCT
force = 10.0
throwforce = 10.0
@@ -94,18 +83,20 @@
var/teleporting = 0
/obj/item/weapon/rcs/New()
+ ..()
processing_objects.Add(src)
+/obj/item/weapon/rcs/examine()
desc = "Use this to send crates and closets to cargo telepads. There are [rcharges] charges left."
+ ..()
/obj/item/weapon/rcs/Del()
processing_objects.Remove(src)
-
+ ..()
/obj/item/weapon/rcs/process()
if(rcharges > 10)
rcharges = 10
if(last_charge == 0)
rcharges++
- desc = "Use this to send crates and closets to cargo telepads. There are [rcharges] charges left."
last_charge = 30
else
last_charge--
@@ -115,11 +106,11 @@
if(mode == 0)
mode = 1
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
- user << "\red The telepad locator has become uncalibrated."
+ user << " The telepad locator has become uncalibrated."
else
mode = 0
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
- user << "\blue You calibrate the telepad locator."
+ user << " You calibrate the telepad locator."
/obj/item/weapon/rcs/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/card/emag) && emagged == 0)
@@ -127,5 +118,5 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
- user << "\red You emag the RCS. Click on it to toggle between modes."
+ user << " You emag the RCS. Click on it to toggle between modes."
return
\ No newline at end of file
diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm
index 471473ed2e9..85232a41068 100644
--- a/code/modules/telesci/telesci_computer.dm
+++ b/code/modules/telesci/telesci_computer.dm
@@ -1,20 +1,52 @@
/obj/machinery/computer/telescience
- name = "Telepad Control Console"
+ name = "\improper Telepad Control Console"
desc = "Used to teleport objects to and from the telescience telepad."
icon_state = "teleport"
+ var/sending = 1
+ var/obj/machinery/telepad/telepad = null
+ var/temp_msg = "Telescience control console initialized.
Welcome."
// VARIABLES //
var/teles_left // How many teleports left until it becomes uncalibrated
- var/x_off // X offset
- var/y_off // Y offset
- var/x_co // X coordinate
- var/y_co // Y coordinate
- var/z_co // Z coordinate
+ var/datum/projectile_data/last_tele_data = null
+ var/z_co = 1
+ var/power_off
+ var/rotation_off
+ var/angle_off
+
+ var/rotation = 0
+ var/angle = 45
+ var/power
+
+ // Based on the power used
+ var/teleport_cooldown = 0
+ var/list/power_options = list(5, 10, 20, 25, 30, 40, 50, 80, 100) // every index requires a bluespace crystal
+ var/teleporting = 0
+ var/starting_crystals = 3
+ var/list/crystals = list()
/obj/machinery/computer/telescience/New()
- teles_left = rand(8,12)
- x_off = rand(-10,10)
- y_off = rand(-10,10)
+ ..()
+ link_telepad()
+ recalibrate()
+
+/obj/machinery/computer/telescience/Del()
+ eject()
+ ..()
+
+/obj/machinery/computer/telescience/examine()
+ ..()
+ usr << "There are [crystals.len] bluespace crystals in the crystal ports."
+
+/obj/machinery/computer/telescience/initialize()
+ ..()
+ link_telepad()
+ for(var/i = 1; i <= starting_crystals; i++)
+ crystals += new /obj/item/bluespace_crystal/artificial(null) // starting crystals
+ power = power_options[1]
+
+/obj/machinery/computer/telescience/proc/link_telepad()
+ telepad = locate() in range(src, 7)
/obj/machinery/computer/telescience/update_icon()
if(stat & BROKEN)
@@ -28,267 +60,250 @@
stat &= ~NOPOWER
/obj/machinery/computer/telescience/attack_paw(mob/user)
- usr << "You are too primitive to use this computer."
+ user << "You are too primitive to use this computer."
return
+/obj/machinery/computer/telescience/attackby(obj/item/W, mob/user)
+ if(istype(W, /obj/item/bluespace_crystal))
+ if(crystals.len >= power_options.len)
+ user << "There are not enough crystal ports."
+ return
+ user.drop_item()
+ crystals += W
+ W.loc = null
+ user.visible_message("[user] inserts a [W] into the [src]'s crystal port.")
+ else
+ ..()
+
/obj/machinery/computer/telescience/attack_ai(mob/user)
- src.attack_hand()
+ src.attack_hand(user)
/obj/machinery/computer/telescience/attack_hand(mob/user)
if(..())
return
- if(stat & (NOPOWER|BROKEN))
- return
- var/t = ""
- t += "Set X"
- t += "Set Y"
- t += "Set Z"
- t += "
Current set coordinates:"
- t += "([x_co], [y_co], [z_co])"
- t += "
Send"
+ interact(user)
+
+/obj/machinery/computer/telescience/interact(mob/user)
+
+ var/t = "