diff --git a/code/modules/research/designs/machine_desings/machine_designs_engi.dm b/code/modules/research/designs/machine_desings/machine_designs_engi.dm
index 4f70b6ee78..8908241b83 100644
--- a/code/modules/research/designs/machine_desings/machine_designs_engi.dm
+++ b/code/modules/research/designs/machine_desings/machine_designs_engi.dm
@@ -104,3 +104,11 @@
build_path = /obj/item/circuitboard/machine/thermomachine
category = list ("Engineering Machinery")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
+
+/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
\ No newline at end of file
diff --git a/code/modules/research/techweb/nodes/bluespace_nodes.dm b/code/modules/research/techweb/nodes/bluespace_nodes.dm
index b0705a0b76..ae9fdd6485 100644
--- a/code/modules/research/techweb/nodes/bluespace_nodes.dm
+++ b/code/modules/research/techweb/nodes/bluespace_nodes.dm
@@ -70,7 +70,7 @@
display_name = "Basic Shuttle Research"
description = "Research the technology required to create and use basic shuttles."
prereq_ids = list("practical_bluespace", "adv_engi")
- design_ids = list("shuttle_creator", "engine_plasma", "engine_heater", "shuttle_control", "shuttle_docker")
+ design_ids = list("shuttle_creator", "engine_plasma", "engine_heater", "shuttle_control", "shuttle_docker","spaceship_navigation_beacon")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
/datum/techweb_node/shuttle_route_upgrade
diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm
index 21a9c6c5d7..36abcb41dc 100644
--- a/code/modules/shuttle/navigation_computer.dm
+++ b/code/modules/shuttle/navigation_computer.dm
@@ -11,6 +11,7 @@
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 = 0
var/x_offset = 0
var/y_offset = 0
@@ -186,7 +187,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
@@ -224,9 +225,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
if(length(whitelist_turfs))
@@ -324,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 0000000000..f1861e0477
--- /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 ..()
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index ed6b50a573..71abfdea8e 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -3343,6 +3343,7 @@
#include "code\modules\shuttle\shuttle.dm"
#include "code\modules\shuttle\shuttle_rotate.dm"
#include "code\modules\shuttle\snaxi.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"