diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index e35dea44cdf..247352fc6a8 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -1224,6 +1224,7 @@
dir = 10
},
/obj/structure/cable,
+/obj/machinery/bluespace_beacon,
/turf/open/floor/plasteel/dark,
/area/mine/maintenance)
"dz" = (
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index 3bd9ccf00d1..659a737f2cb 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -9,6 +9,7 @@ SUBSYSTEM_DEF(shuttle)
var/list/mobile = list()
var/list/stationary = list()
+ var/list/beacons = list()
var/list/transit = list()
var/list/transit_requesters = list()
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index 3fe4091dc22..5a581d13510 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -586,3 +586,11 @@
build_path = /obj/item/circuitboard/machine/stasis
category = list("Medical Machinery")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+
+/datum/design/board/spaceship_navigation_beacon
+ name = "Machine Design (Bluespace Navigation Gigabeacon)"
+ desc = "The circuit board for a Bluespace Navigation Gigabeacon."
+ id = "spaceship_navigation_beacon"
+ build_path = /obj/item/circuitboard/machine/spaceship_navigation_beacon
+ category = list ("Teleportation Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index bbf40c72404..68a46df93de 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -230,6 +230,15 @@
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
+/datum/techweb_node/regulated_bluespace
+ id = "regulated_bluespace"
+ display_name = "Regulated Bluespace Research"
+ description = "Bluespace technology using stable and balanced procedures. Required by galactic convention for public use."
+ prereq_ids = list("base")
+ design_ids = list("spaceship_navigation_beacon")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
+ export_price = 2500
+
/datum/techweb_node/unregulated_bluespace
id = "unregulated_bluespace"
display_name = "Unregulated Bluespace Research"
diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm
index 6502f1fedaa..68e2e58dd59 100644
--- a/code/modules/shuttle/navigation_computer.dm
+++ b/code/modules/shuttle/navigation_computer.dm
@@ -10,10 +10,11 @@
var/list/jumpto_ports = list() //hashset of ports to jump to and ignore for collision purposes
var/obj/docking_port/stationary/my_port //the custom docking port placed by this console
var/obj/docking_port/mobile/shuttle_port //the mobile docking port of the connected shuttle
+ var/list/locked_traits = list(ZTRAIT_RESERVED, ZTRAIT_CENTCOM, ZTRAIT_AWAY, ZTRAIT_REEBE) //traits forbided for custom docking
var/view_range = 7
var/x_offset = 0
var/y_offset = 0
- var/space_turfs_only = TRUE
+ var/list/whitelist_turfs = list(/turf/open/space, /turf/open/floor/plating, /turf/open/lava)
var/see_hidden = FALSE
var/designate_time = 0
var/turf/designating_target_loc
@@ -28,6 +29,7 @@
var/obj/docking_port/stationary/S = V
if(jumpto_ports[S.id])
z_lock |= S.z
+ whitelist_turfs = typecacheof(whitelist_turfs)
/obj/machinery/computer/camera_advanced/shuttle_docker/Destroy()
. = ..()
@@ -144,6 +146,7 @@
my_port.hidden = shuttle_port.hidden
my_port.setDir(the_eye.dir)
my_port.forceMove(locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z))
+
if(current_user.client)
current_user.client.images -= the_eye.placed_images
@@ -161,7 +164,7 @@
if(current_user.client)
current_user.client.images += the_eye.placed_images
to_chat(current_user, "Transit location designated")
- return
+ return TRUE
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/canDesignateTarget()
if(!designating_target_loc || !current_user || (eyeobj.loc != designating_target_loc) || (stat & (NOPOWER|BROKEN)) )
@@ -189,7 +192,7 @@
var/turf/eyeturf = get_turf(the_eye)
if(!eyeturf)
return SHUTTLE_DOCKER_BLOCKED
- if(z_lock.len && !(eyeturf.z in z_lock))
+ if(!eyeturf.z || SSmapping.level_has_any_trait(eyeturf.z, locked_traits))
return SHUTTLE_DOCKER_BLOCKED
. = SHUTTLE_DOCKER_LANDING_CLEAR
@@ -227,9 +230,9 @@
if(hidden_turf_info)
. = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT
- if(space_turfs_only)
+ if(length(whitelist_turfs))
var/turf_type = hidden_turf_info ? hidden_turf_info[2] : T.type
- if(!ispath(turf_type, /turf/open/space))
+ if(!is_type_in_typecache(turf_type, whitelist_turfs))
return SHUTTLE_DOCKER_BLOCKED
// Checking for overlapping dock boundaries
@@ -322,12 +325,25 @@
var/list/L = list()
for(var/V in SSshuttle.stationary)
if(!V)
+ stack_trace("SSshuttle.stationary have null entry!")
continue
var/obj/docking_port/stationary/S = V
if(console.z_lock.len && !(S.z in console.z_lock))
continue
if(console.jumpto_ports[S.id])
- L[S.name] = S
+ L["([L.len])[S.name]"] = S
+
+ for(var/V in SSshuttle.beacons)
+ if(!V)
+ stack_trace("SSshuttle.beacons have null entry!")
+ continue
+ var/obj/machinery/spaceship_navigation_beacon/nav_beacon = V
+ if(!nav_beacon.z || SSmapping.level_has_any_trait(nav_beacon.z, console.locked_traits))
+ break
+ if(!nav_beacon.locked)
+ L["([L.len]) [nav_beacon.name] located: [nav_beacon.x] [nav_beacon.y] [nav_beacon.z]"] = nav_beacon
+ else
+ L["([L.len]) [nav_beacon.name] locked"] = null
playsound(console, 'sound/machines/terminal_prompt.ogg', 25, 0)
var/selected = input("Choose location to jump to", "Locations", null) as null|anything in L
diff --git a/code/modules/shuttle/spaceship_navigation_beacon.dm b/code/modules/shuttle/spaceship_navigation_beacon.dm
new file mode 100644
index 00000000000..b1572f3460a
--- /dev/null
+++ b/code/modules/shuttle/spaceship_navigation_beacon.dm
@@ -0,0 +1,63 @@
+/obj/item/circuitboard/machine/spaceship_navigation_beacon
+ name = "Bluespace Navigation Gigabeacon (Machine Board)"
+ build_path = /obj/machinery/spaceship_navigation_beacon
+ req_components = list()
+
+
+/obj/machinery/spaceship_navigation_beacon
+ name = "Bluespace Navigation Gigabeacon"
+ desc = "A device that creates a bluespace anchor that allow ships jump near to it."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "core"
+ use_power = IDLE_POWER_USE
+ idle_power_usage = 0
+ density = TRUE
+ circuit = /obj/item/circuitboard/machine/spaceship_navigation_beacon
+
+ var/locked = FALSE //Locked beacons don't allow to jump to it.
+
+
+/obj/machinery/spaceship_navigation_beacon/Initialize()
+ . = ..()
+ SSshuttle.beacons |= src
+
+obj/machinery/spaceship_navigation_beacon/emp_act()
+ locked = TRUE
+
+/obj/machinery/spaceship_navigation_beacon/Destroy()
+ SSshuttle.beacons -= src
+ return ..()
+
+// update the icon_state
+/obj/machinery/spaceship_navigation_beacon/update_icon()
+ if(powered())
+ icon_state = "core"
+ else
+ icon_state = "core-open"
+
+/obj/machinery/spaceship_navigation_beacon/power_change()
+ . = ..()
+ update_icon()
+
+/obj/machinery/spaceship_navigation_beacon/multitool_act(mob/living/user, obj/item/multitool/I)
+ if(panel_open)
+ var/new_name = "Beacon_[input("Enter the custom name for this beacon", "It be Beacon ..your input..") as text]"
+ if(new_name && Adjacent(user))
+ name = new_name
+ to_chat(user, "You change beacon name to [name].")
+ else
+ locked =!locked
+ to_chat(user, "You [locked ? "" : "un"]lock [src].")
+ return TRUE
+
+/obj/machinery/spaceship_navigation_beacon/examine()
+ .=..()
+ . += "Status: [locked ? "LOCKED" : "Stable"] "
+
+/obj/machinery/spaceship_navigation_beacon/attackby(obj/item/W, mob/user, params)
+ if(default_deconstruction_screwdriver(user, "core-open", "core", W))
+ return
+ if(default_deconstruction_crowbar(W))
+ return
+
+ return ..()
diff --git a/tgstation.dme b/tgstation.dme
index 0d508d0cfc2..ca85abf8a2f 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2697,6 +2697,7 @@
#include "code\modules\shuttle\ripple.dm"
#include "code\modules\shuttle\shuttle.dm"
#include "code\modules\shuttle\shuttle_rotate.dm"
+#include "code\modules\shuttle\spaceship_navigation_beacon.dm"
#include "code\modules\shuttle\special.dm"
#include "code\modules\shuttle\supply.dm"
#include "code\modules\shuttle\syndicate.dm"