diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 229acc1683e..f68de313496 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -180,6 +180,6 @@
return 0
- if(destination.z > 7) //Away mission z-levels
+ if(destination.z == 7) //Away mission z-levels
return 0
return 1
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 0d1d50c8d56..cbc7cce5e78 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -142,6 +142,10 @@
update_icon()
return 0
+/obj/effect/blob/Crossed(var/mob/living/L)
+ ..()
+ L.blob_act()
+
/obj/effect/blob/attackby(var/obj/item/weapon/W, var/mob/user)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm
index 054fb163a4f..528e9222117 100644
--- a/code/modules/mob/camera/camera.dm
+++ b/code/modules/mob/camera/camera.dm
@@ -3,6 +3,7 @@
/mob/camera
name = "camera mob"
density = 0
+ anchored = 1
status_flags = GODMODE // You can't damage it.
mouse_opacity = 0
see_in_dark = 7
diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm
index 50e14ee6d37..49038693074 100644
--- a/code/modules/reagents/Chemistry-Recipes.dm
+++ b/code/modules/reagents/Chemistry-Recipes.dm
@@ -1468,6 +1468,19 @@ datum
sleep(20)
M.client.screen -= blueeffect
del(blueeffect)
+ slimecrystal
+ name = "Slime Crystal"
+ id = "m_crystal"
+ result = null
+ required_reagents = list("blood" = 5)
+ result_amount = 1
+ required_container = /obj/item/slime_extract/bluespace
+ required_other = 1
+ on_reaction(var/datum/reagents/holder, var/created_volume)
+ feedback_add_details("slime_cores_used","[replacetext(name," ","_")]")
+ if(holder.my_atom)
+ var/obj/item/bluespace_crystal/BC = new(get_turf(holder.my_atom))
+ BC.visible_message("The [BC] appears out of thin air!")
//Cerulean
diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm
index c6a2060150a..6177fbde9f9 100644
--- a/code/modules/research/designs.dm
+++ b/code/modules/research/designs.dm
@@ -1574,6 +1574,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////////////////////
/////////////////////////////////////////
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/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm
index 3dbd24ad0d8..85232a41068 100644
--- a/code/modules/telesci/telesci_computer.dm
+++ b/code/modules/telesci/telesci_computer.dm
@@ -11,6 +11,8 @@
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
@@ -18,17 +20,32 @@
// Based on the power used
var/teleport_cooldown = 0
- var/list/power_options = list(5, 10, 25, 50, 100) //
+ 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()
..()
+ link_telepad()
recalibrate()
- power = power_options[1]
- initialize()
+
+/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()
@@ -46,6 +63,18 @@
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(user)
@@ -64,11 +93,14 @@
t += "Set Power"
t += "
"
- for(var/pwr in power_options)
- if(power == pwr)
- t += "
[pwr]"
+ for(var/i = 1; i <= power_options.len; i++)
+ if(crystals.len < i)
+ t += "
[power_options[i]]"
continue
- t += "
[pwr]"
+ if(power == power_options[i])
+ t += "
[power_options[i]]"
+ continue
+ t += "
[power_options[i]]"
t += "
"
t += "Set Sector"
@@ -76,7 +108,7 @@
t += "
Send"
t += " Receive"
- t += "
Recalibrate"
+ t += "
Recalibrate Crystals Eject Crystals"
// Information about the last teleport
t += "
"
@@ -84,8 +116,8 @@
t += "No teleport data found."
else
t += "Source Location: ([last_tele_data.src_x], [last_tele_data.src_y])
"
- t += "Distance: [last_tele_data.distance]m
"
- t += "Time: [last_tele_data.time] secs
"
+ //t += "Distance: [round(last_tele_data.distance, 0.1)]m
"
+ t += "Time: [round(last_tele_data.time, 0.1)] secs
"
t += "
"
var/datum/browser/popup = new(user, "telesci", name, 300, 500)
@@ -95,9 +127,8 @@
/obj/machinery/computer/telescience/proc/sparks()
if(telepad)
- var/L = get_turf(E)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, L)
+ s.set_up(5, 1, get_turf(telepad))
s.start()
else
return
@@ -120,9 +151,10 @@
if(telepad)
var/truePower = Clamp(power + power_off, 1, 1000)
- var/trueRotation = rotation
+ var/trueRotation = rotation + rotation_off
+ var/trueAngle = Clamp(angle + angle_off, 1, 90)
- var/datum/projectile_data/proj_data = projectile_trajectory(telepad.x, telepad.y, trueRotation, angle, truePower)
+ var/datum/projectile_data/proj_data = projectile_trajectory(telepad.x, telepad.y, trueRotation, trueAngle, truePower)
last_tele_data = proj_data
var/trueX = Clamp(round(proj_data.dest_x, 1), 1, world.maxx)
@@ -141,6 +173,10 @@
spawn(round(proj_data.time) * 10) // in seconds
+ if(!telepad)
+ return
+ if(telepad.stat & NOPOWER)
+ return
teleporting = 0
teleport_cooldown = world.time + (power * 2)
teles_left -= 1
@@ -149,48 +185,60 @@
use_power(power * 10)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
-
- s.set_up(5, 1, telepad)
+ s.set_up(5, 1, get_turf(telepad))
s.start()
+
temp_msg = "Teleport successful.
"
if(teles_left < 10)
temp_msg += "
Calibration required soon."
else
temp_msg += "Data printed below."
investigate_log("[key_name(usr)]/[user] has teleported with Telescience at [trueX],[trueY],[z_co], in [A ? A.name : "null area"].","telesci")
+
var/sparks = get_turf(target)
var/datum/effect/effect/system/spark_spread/y = new /datum/effect/effect/system/spark_spread
y.set_up(5, 1, sparks)
y.start()
+
var/turf/source = target
var/turf/dest = get_turf(telepad)
if(sending)
source = dest
dest = target
+
flick("pad-beam", telepad)
playsound(telepad.loc, 'sound/weapons/emitter2.ogg', 25, 1)
for(var/atom/movable/ROI in source)
- if(!ismob(ROI) && ROI.anchored) continue
- do_teleport(ROI, dest, 0)
+ // if is anchored, don't let through
+ if(ROI.anchored)
+ if(isliving(ROI))
+ var/mob/living/L = ROI
+ if(L.buckled)
+ // TP people on office chairs
+ if(L.buckled.anchored)
+ continue
+ else
+ continue
+ else if(!isobserver(ROI))
+ continue
+ do_teleport(ROI, dest)
updateDialog()
-// TO DO: add projectile_trajectory to telesci
-
/obj/machinery/computer/telescience/proc/teleport(mob/user)
if(rotation == null || angle == null || z_co == null)
temp_msg = "ERROR!
Set a angle, rotation and sector."
return
- if(rotation < 0 || rotation > 360)
+ if(power <= 0)
telefail()
- temp_msg = "ERROR!
Bearing is less than 0 or greater than 360."
+ temp_msg = "ERROR!
No power selected!"
return
if(angle < 1 || angle > 90)
telefail()
temp_msg = "ERROR!
Elevation is less than 1 or greater than 90."
return
- if(z_co == 2 || z_co < 1 || z_co > 7)
+ if(z_co == 2 || z_co < 1 || z_co > 6)
telefail()
- temp_msg = "ERROR! Sector is less than 1,
greater than 7, or equal to 2."
+ temp_msg = "ERROR! Sector is less than 1,
greater than 6, or equal to 2."
return
if(teles_left > 0)
doteleport(user)
@@ -200,6 +248,12 @@
return
return
+/obj/machinery/computer/telescience/proc/eject()
+ for(var/obj/item/I in crystals)
+ I.loc = src.loc
+ crystals -= I
+ power = 0
+
/obj/machinery/computer/telescience/Topic(href, href_list)
if(..())
return
@@ -207,8 +261,8 @@
var/new_rot = input("Please input desired bearing in degrees.", name, rotation) as num
if(..()) // Check after we input a value, as they could've moved after they entered something
return
- rotation = Clamp(round(new_rot, 0.1), -9999, 9999)
- rotation = SimplifyDegrees(rotation)
+ rotation = Clamp(new_rot, -900, 900)
+ rotation = round(rotation, 0.01)
if(href_list["setangle"])
var/new_angle = input("Please input desired elevation in degrees.", name, angle) as num
@@ -217,16 +271,17 @@
angle = Clamp(round(new_angle, 0.1), 1, 9999)
if(href_list["setpower"])
- var/pwr = href_list["setpower"]
- pwr = text2num(pwr)
- if(pwr != null && pwr in power_options)
- power = pwr
+ var/index = href_list["setpower"]
+ index = text2num(index)
+ if(index != null && power_options[index])
+ if(crystals.len >= index)
+ power = power_options[index]
if(href_list["setz"])
var/new_z = input("Please input desired sector.", name, z_co) as num
if(..())
return
- z_co = Clamp(new_z, 1, 10)
+ z_co = Clamp(round(new_z), 1, 10)
if(href_list["send"])
sending = 1
@@ -241,8 +296,14 @@
sparks()
temp_msg = "NOTICE:
Calibration successful."
+ if(href_list["eject"])
+ eject()
+ temp_msg = "NOTICE:
Bluespace crystals ejected."
+
updateDialog()
/obj/machinery/computer/telescience/proc/recalibrate()
- teles_left = rand(40, 50)
- power_off = rand(-10, 10)
\ No newline at end of file
+ teles_left = rand(30, 40)
+ angle_off = rand(-25, 25)
+ power_off = rand(-4, 0)
+ rotation_off = rand(-10, 10)
\ No newline at end of file
diff --git a/icons/obj/telescience.dmi b/icons/obj/telescience.dmi
index 1f3344f2e48..4e8251beac3 100644
Binary files a/icons/obj/telescience.dmi and b/icons/obj/telescience.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 9280c14decf..a454b46ea68 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1177,6 +1177,7 @@
#include "code\modules\surgery\xenomorph_removal.dm"
#include "code\modules\surgery\organs\helpers.dm"
#include "code\modules\surgery\organs\organ.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"