diff --git a/baystation12.dme b/baystation12.dme
index 37d93bc811..fa8394afdb 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -552,6 +552,7 @@
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\scanners.dm"
+#include "code\game\objects\items\devices\spy_bug.dm"
#include "code\game\objects\items\devices\suit_cooling.dm"
#include "code\game\objects\items\devices\taperecorder.dm"
#include "code\game\objects\items\devices\traitordevices.dm"
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 5a95784273..0cfc8dd1ed 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -45,11 +45,12 @@
"Stealthy and Inconspicuous Weapons" = list(
new/datum/uplink_item(/obj/item/weapon/soap/syndie, 1, "Subversive Soap", "SP"),
new/datum/uplink_item(/obj/item/weapon/cartridge/syndicate, 3, "Detomatix PDA Cartridge", "DC"),
- new/datum/uplink_item(/obj/item/weapon/pen/paralysis, 3, "Paralysis Pen", "PP")
+ new/datum/uplink_item(/obj/item/weapon/pen/paralysis, 3, "Paralysis Pen", "PP"),
),
"Stealth and Camouflage Items" = list(
new/datum/uplink_item(/obj/item/weapon/card/id/syndicate, 2, "Agent ID card", "AC"),
new/datum/uplink_item(/obj/item/clothing/shoes/syndigaloshes, 2, "No-Slip Shoes", "SH"),
+ new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/spy, 2, "Spy Kit", "SK"),
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/chameleon, 3, "Chameleon Kit", "CB"),
new/datum/uplink_item(/obj/item/device/chameleon, 4, "Chameleon-Projector", "CP"),
new/datum/uplink_item(/obj/item/clothing/mask/gas/voice, 4, "Voice Changer", "VC")
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 24c44694f5..93ce1d9eab 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -115,13 +115,10 @@
listening = !listening && !(wires.IsIndexCut(WIRE_RECEIVE) || wires.IsIndexCut(WIRE_SIGNAL))
/obj/item/device/radio/Topic(href, href_list)
- //..()
- if (usr.stat || !on)
- return
-
- if (!(issilicon(usr) || (usr.contents.Find(src) || ( in_range(src, usr) && istype(loc, /turf) ))))
+ if(..() || !on)
usr << browse(null, "window=radio")
return
+
usr.set_machine(src)
if (href_list["track"])
var/mob/target = locate(href_list["track"])
@@ -152,17 +149,7 @@
else
channels[chan_name] |= FREQ_LISTENING
- if (!( master ))
- if (istype(loc, /mob))
- interact(loc)
- else
- updateDialog()
- else
- if (istype(master.loc, /mob))
- interact(master.loc)
- else
- updateDialog()
- add_fingerprint(usr)
+ interact(usr)
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT
var/datum/radio_frequency/connection = null
diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm
new file mode 100644
index 0000000000..208838960b
--- /dev/null
+++ b/code/game/objects/items/devices/spy_bug.dm
@@ -0,0 +1,138 @@
+/obj/item/device/spy_bug
+ name = "tiny device"
+ desc = "It looks like a tiny camera, microphone, and transmission device in a happy union. Also mass-fabricated."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "eshield0"
+ item_state = "nothing"
+ layer = TURF_LAYER+0.2
+
+ flags = CONDUCT
+ force = 5.0
+ w_class = 1.0
+ throwforce = 5.0
+ throw_range = 15
+ throw_speed = 3
+
+ origin_tech = "programming=1;engineering=1;syndicate=3"
+
+ var/obj/item/device/radio/spy/radio
+ var/obj/machinery/camera/spy/camera
+
+/obj/item/device/spy_bug/New()
+ ..()
+ radio = new(src)
+ camera = new(src)
+
+/obj/item/device/spy_bug/attack_self(mob/user)
+ radio.attack_self(user)
+
+/obj/item/device/spy_bug/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
+ radio.hear_talk(M, msg, speaking)
+
+
+/obj/item/device/spy_monitor
+ name = "\improper PDA"
+ desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
+ icon = 'icons/obj/pda.dmi'
+ icon_state = "pda"
+ item_state = "electronic"
+
+ w_class = 2.0
+
+ origin_tech = "programming=1;engineering=1;syndicate=3"
+
+ var/operating = 0
+ var/obj/item/device/radio/spy/radio
+ var/obj/machinery/camera/spy/selected_camera
+ var/list/obj/machinery/camera/spy/cameras = new()
+
+/obj/item/device/spy_monitor/New()
+ radio = new(src)
+
+/obj/item/device/spy_monitor/examine(mob/user)
+ if(..(user, 1))
+ user << "The time '12:00' is blinking in the corner of the screen. \The [src] looks very cheaply made."
+
+/obj/item/device/spy_monitor/attack_self(mob/user)
+ if(operating)
+ return
+
+ radio.attack_self(user)
+ view_cameras(user)
+
+/obj/item/device/spy_monitor/attackby(obj/W as obj, mob/living/user as mob)
+ if(istype(W, /obj/item/device/spy_bug))
+ var/obj/item/device/spy_bug/SB = W
+ if(SB.camera in cameras)
+ user << "\The [SB] has been unpaired from \the [src]."
+ cameras -= SB.camera
+ else
+ user << "\The [SB] has been paired with \the [src]."
+ cameras += SB.camera
+ else
+ return ..()
+
+/obj/item/device/spy_monitor/proc/view_cameras(mob/user)
+ if(!can_use_cam(user))
+ return
+
+ selected_camera = cameras[1]
+ view_camera(user)
+
+ operating = 1
+ while(selected_camera && Adjacent(user))
+ selected_camera = input("Select camera bug to view.") as null|anything in cameras
+ selected_camera = null
+ operating = 0
+
+/obj/item/device/spy_monitor/proc/view_camera(mob/user)
+ spawn(0)
+ while(selected_camera && Adjacent(user))
+ var/turf/T = get_turf(selected_camera)
+ if(!T || T.z != user.z)
+ user.unset_machine()
+ user.reset_view(null)
+ user << "[selected_camera] out of range."
+ sleep(90)
+ else
+ user.set_machine(selected_camera)
+ user.reset_view(selected_camera)
+ sleep(10)
+ user.unset_machine()
+ user.reset_view(null)
+
+/obj/item/device/spy_monitor/proc/can_use_cam(mob/user)
+ if(operating)
+ return
+
+ if(!cameras.len)
+ user << "No paired cameras detected!"
+ user << "Bring a bug in contact with this device to pair the camera."
+ return
+
+ return 1
+
+/obj/item/device/spy_monitor/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
+ return radio.hear_talk(M, msg, speaking)
+
+
+/obj/machinery/camera/spy
+ // These cheap toys are accessible from the mercenary camera console as well
+ network = list("NUKE")
+
+/obj/machinery/camera/spy/New()
+ ..()
+ name = "DV-136ZB #[rand(1000,9999)]"
+ c_tag = name
+ cameranet.removeCamera(src) // Sorry, no AI spying.
+
+/obj/machinery/camera/spy/check_eye(var/mob/user as mob)
+ return 1
+
+/obj/item/device/radio/spy
+ listening = 0
+ frequency = 1473
+ broadcasting = 0
+ canhear_range = 1
+ name = "spy device"
+ icon_state = "syn_cypherkey"
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index fc1d2e2b8a..205fb3d0a1 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -149,3 +149,14 @@
..()
new /obj/item/weapon/stamp/chameleon(src)
new /obj/item/weapon/pen/chameleon(src)
+
+/obj/item/weapon/storage/box/syndie_kit/spy
+ name = "spy kit"
+ desc = "For when you want to conduct voyeurism from afar."
+
+/obj/item/weapon/storage/box/syndie_kit/spy/New()
+ ..()
+ new /obj/item/device/spy_bug(src)
+ new /obj/item/device/spy_bug(src)
+ new /obj/item/device/spy_bug(src)
+ new /obj/item/device/spy_monitor(src)
diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi
index b70af9c656..ffbdbeaa0c 100644
Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ
diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi
index c6183f6ff5..b8e3754e1b 100644
Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ