diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm
index 7a8552607b5..0d9eb6e91f9 100644
--- a/code/game/machinery/quantum_pad.dm
+++ b/code/game/machinery/quantum_pad.dm
@@ -73,16 +73,27 @@
else
to_chat(user, "There is no quantum pad data saved in [I]'s buffer!")
return TRUE
+
+ else if(istype(I, /obj/item/quantum_keycard))
+ var/obj/item/quantum_keycard/K = I
+ if(K.qpad)
+ to_chat(user, "You insert [K] into [src]'s card slot, activating it.")
+ interact(user, K.qpad)
+ else
+ to_chat(user, "You insert [K] into [src]'s card slot, initiating the link procedure.")
+ if(do_after(user, 40, target = src))
+ to_chat(user, "You complete the link between [K] and [src].")
+ K.qpad = src
if(default_deconstruction_crowbar(I))
return
return ..()
-/obj/machinery/quantumpad/interact(mob/user)
- if(!linked_pad || QDELETED(linked_pad))
+/obj/machinery/quantumpad/interact(mob/user, obj/machinery/quantumpad/target_pad = linked_pad)
+ if(!target_pad || QDELETED(target_pad))
if(!map_pad_link_id || !initMappedLink())
- to_chat(user, "There is no linked pad!")
+ to_chat(user, "Target pad not found!")
return
if(world.time < last_teleport + teleport_cooldown)
@@ -93,15 +104,15 @@
to_chat(user, "[src] is charging up. Please wait.")
return
- if(linked_pad.teleporting)
- to_chat(user, "Linked pad is busy. Please wait.")
+ if(target_pad.teleporting)
+ to_chat(user, "Target pad is busy. Please wait.")
return
- if(linked_pad.stat & NOPOWER)
- to_chat(user, "Linked pad is not responding to ping.")
+ if(target_pad.stat & NOPOWER)
+ to_chat(user, "Target pad is not responding to ping.")
return
add_fingerprint(user)
- doteleport(user)
+ doteleport(user, target_pad)
/obj/machinery/quantumpad/proc/sparks()
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
@@ -117,8 +128,8 @@
if(linked_pad)
ghost.forceMove(get_turf(linked_pad))
-/obj/machinery/quantumpad/proc/doteleport(mob/user)
- if(linked_pad)
+/obj/machinery/quantumpad/proc/doteleport(mob/user, obj/machinery/quantumpad/target_pad = linked_pad)
+ if(target_pad)
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, 1)
teleporting = TRUE
@@ -130,7 +141,7 @@
to_chat(user, "[src] is unpowered!")
teleporting = FALSE
return
- if(!linked_pad || QDELETED(linked_pad) || linked_pad.stat & NOPOWER)
+ if(!target_pad || QDELETED(target_pad) || target_pad.stat & NOPOWER)
to_chat(user, "Linked pad is not responding to ping. Teleport aborted.")
teleporting = FALSE
return
@@ -141,12 +152,12 @@
// use a lot of power
use_power(10000 / power_efficiency)
sparks()
- linked_pad.sparks()
+ target_pad.sparks()
flick("qpad-beam", src)
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
- flick("qpad-beam", linked_pad)
- playsound(get_turf(linked_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
+ flick("qpad-beam", target_pad)
+ playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
for(var/atom/movable/ROI in get_turf(src))
// if is anchored, don't let through
if(ROI.anchored)
@@ -160,7 +171,7 @@
continue
else if(!isobserver(ROI))
continue
- do_teleport(ROI, get_turf(linked_pad))
+ do_teleport(ROI, get_turf(target_pad))
/obj/machinery/quantumpad/proc/initMappedLink()
. = FALSE
diff --git a/code/game/objects/items/devices/quantum_keycard.dm b/code/game/objects/items/devices/quantum_keycard.dm
new file mode 100644
index 00000000000..0d96d7604ae
--- /dev/null
+++ b/code/game/objects/items/devices/quantum_keycard.dm
@@ -0,0 +1,32 @@
+/obj/item/quantum_keycard
+ name = "quantum keycard"
+ desc = "A keycard able to link to a quantum pad's particle signature, allowing other quantum pads to travel there instead of their linked pad."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "quantum_keycard"
+ item_state = "card-id"
+ lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
+ w_class = WEIGHT_CLASS_TINY
+ var/obj/machinery/quantumpad/qpad
+
+/obj/item/quantum_keycard/examine(mob/user)
+ ..()
+ if(qpad)
+ to_chat(user, "It's currently linked to a quantum pad.")
+ to_chat(user, "Alt-click to unlink the keycard.")
+ else
+ to_chat(user, "Insert [src] into an active quantum pad to link it.")
+
+/obj/item/quantum_keycard/AltClick(mob/living/user)
+ if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+ return
+ to_chat(user, "You start pressing [src]'s unlink button...")
+ if(do_after(user, 40, target = src))
+ to_chat(user, "The keycard beeps twice and disconnects the quantum link.")
+ qpad = null
+
+/obj/item/quantum_keycard/update_icon()
+ if(qpad)
+ icon_state = "quantum_keycard_on"
+ else
+ icon_state = initial(icon_state)
\ No newline at end of file
diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm
index 08c30ade78d..e7b4592ccc1 100644
--- a/code/modules/research/designs/misc_designs.dm
+++ b/code/modules/research/designs/misc_designs.dm
@@ -206,6 +206,16 @@
build_path = /obj/item/locator
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
+/datum/design/quantum_keycard
+ name = "Quantum Keycard"
+ desc = "Allows for the construction of a quantum keycard."
+ id = "quantum_keycard"
+ build_type = PROTOLATHE
+ materials = list(MAT_GLASS = 500, MAT_METAL = 500, MAT_SILVER = 500, MAT_BLUESPACE = 1000)
+ build_path = /obj/item/quantum_keycard
+ category = list("Equipment")
+ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/anomaly_neutralizer
name = "Anomaly Neutralizer"
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index f105010697b..0fadfdeee0f 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -171,18 +171,26 @@
display_name = "Basic Bluespace Theory"
description = "Basic studies into the mysterious alternate dimension known as bluespace."
prereq_ids = list("base")
- design_ids = list("beacon", "xenobioconsole", "telesci_gps")
+ design_ids = list("beacon", "xenobioconsole", "telesci_gps", "bluespace_crystal")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
-/datum/techweb_node/adv_bluespace
- id = "adv_bluespace"
- display_name = "Advanced Bluespace Research"
- description = "Deeper understanding of how the Bluespace dimension works"
- prereq_ids = list("practical_bluespace", "high_efficiency")
- design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "tele_station", "tele_hub", "quantumpad", "launchpad", "launchpad_console",
- "teleconsole", "bag_holding", "bluespace_crystal", "wormholeprojector", "bluespace_pod")
- research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 15000)
+/datum/techweb_node/bluespace_travel
+ id = "bluespace_travel"
+ display_name = "Bluespace Travel"
+ description = "Application of Bluespace for static teleportation technology."
+ prereq_ids = list("practical_bluespace")
+ design_ids = list("tele_station", "tele_hub", "quantumpad", "launchpad", "launchpad_console", "bluespace_pod")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
+ export_price = 5000
+
+/datum/techweb_node/micro_bluespace
+ id = "micro_bluespace"
+ display_name = "Miniaturized Bluespace Research"
+ description = "Extreme reduction in space required for bluespace engines, leading to portable bluespace technology."
+ prereq_ids = list("bluespace_travel", "practical_bluespace", "high_efficiency")
+ design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "bag_holding", "quantum_keycard", "wormholeprojector")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
/datum/techweb_node/practical_bluespace
@@ -198,7 +206,7 @@
id = "bluespace_power"
display_name = "Bluespace Power Technology"
description = "Even more powerful.. power!"
- prereq_ids = list("adv_power", "adv_bluespace")
+ prereq_ids = list("adv_power", "practical_bluespace")
design_ids = list("bluespace_cell", "quadratic_capacitor")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index becb58568ff..22a790bb870 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 67706de109e..082d562020a 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -841,6 +841,7 @@
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\pressureplates.dm"
+#include "code\game\objects\items\devices\quantum_keycard.dm"
#include "code\game\objects\items\devices\reverse_bear_trap.dm"
#include "code\game\objects\items\devices\scanners.dm"
#include "code\game\objects\items\devices\sensor_device.dm"