diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 95f1cb283c..27f366f7f8 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -24458,7 +24458,7 @@
/area/crew_quarters/heads/captain)
"bfE" = (
/obj/structure/table/wood,
-/obj/item/pinpointer,
+/obj/item/pinpointer/nuke,
/obj/item/disk/nuclear,
/obj/item/storage/secure/safe{
pixel_x = 35;
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 5e0ded4416..0484d95b79 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -53210,7 +53210,7 @@
/area/tcommsat/server)
"bYo" = (
/obj/structure/table/wood,
-/obj/item/pinpointer,
+/obj/item/pinpointer/nuke,
/obj/item/disk/nuclear,
/obj/item/device/radio/intercom{
name = "Station Intercom";
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index ec76a564d5..a60e43dd83 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -29108,7 +29108,7 @@
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/structure/table/wood,
-/obj/item/pinpointer,
+/obj/item/pinpointer/nuke,
/obj/item/disk/nuclear,
/turf/open/floor/carpet,
/area/crew_quarters/heads/captain/private)
diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm
index 9a3b2b9454..6b4f65c67e 100644
--- a/_maps/map_files/OmegaStation/OmegaStation.dmm
+++ b/_maps/map_files/OmegaStation/OmegaStation.dmm
@@ -1187,7 +1187,7 @@
pixel_x = 32;
pixel_y = 24
},
-/obj/item/pinpointer,
+/obj/item/pinpointer/nuke,
/obj/item/disk/nuclear,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 10
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index 7f55c286c7..497bf0a4ce 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -13937,7 +13937,7 @@
/area/storage/primary)
"aEx" = (
/obj/structure/table/wood,
-/obj/item/pinpointer,
+/obj/item/pinpointer/nuke,
/obj/item/disk/nuclear,
/obj/machinery/light{
dir = 8
diff --git a/code/__DEFINES/pinpointers.dm b/code/__DEFINES/pinpointers.dm
index 80403e54de..75f0452ea9 100644
--- a/code/__DEFINES/pinpointers.dm
+++ b/code/__DEFINES/pinpointers.dm
@@ -2,6 +2,3 @@
#define TRACK_NUKE_DISK 1 //We track the nuclear authentication disk, either to protect it or steal it
#define TRACK_MALF_AI 2 //We track the malfunctioning AI, so we can prevent it from blowing us all up
#define TRACK_INFILTRATOR 3 //We track the Syndicate infiltrator, so we can get back to ship when the nuke's armed
-#define TRACK_OPERATIVES 4 //We track the closest operative, so we can regroup when we need to
-#define TRACK_ATOM 5 //We track a specified atom, so admins can make us function for events
-#define TRACK_COORDINATES 6 //We point towards the specified coordinates on our z-level, so we can navigate
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm.rej b/code/game/gamemodes/malfunction/Malf_Modules.dm.rej
new file mode 100644
index 0000000000..97dbe2bbdb
--- /dev/null
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm.rej
@@ -0,0 +1,11 @@
+diff a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm (rejected hunks)
+@@ -309,8 +309,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
+ owner_AI.nuking = TRUE
+ owner_AI.doomsday_device = DOOM
+ owner_AI.doomsday_device.start()
+- for(var/pinpointer in GLOB.pinpointer_list)
+- var/obj/item/weapon/pinpointer/P = pinpointer
++ for(var/obj/item/weapon/pinpointer/nuke/P in GLOB.pinpointer_list)
+ P.switch_mode_to(TRACK_MALF_AI) //Pinpointers start tracking the AI wherever it goes
+ qdel(src)
+
diff --git a/code/game/gamemodes/nuclear/nuclear.dm.rej b/code/game/gamemodes/nuclear/nuclear.dm.rej
new file mode 100644
index 0000000000..19648547c7
--- /dev/null
+++ b/code/game/gamemodes/nuclear/nuclear.dm.rej
@@ -0,0 +1,10 @@
+diff a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm (rejected hunks)
+@@ -325,7 +325,7 @@
+ gloves = /obj/item/clothing/gloves/combat
+ back = /obj/item/weapon/storage/backpack
+ ears = /obj/item/device/radio/headset/syndicate/alt
+- l_pocket = /obj/item/weapon/pinpointer/syndicate
++ l_pocket = /obj/item/weapon/pinpointer/nuke/syndicate
+ id = /obj/item/weapon/card/id/syndicate
+ belt = /obj/item/weapon/gun/ballistic/automatic/pistol
+ backpack_contents = list(/obj/item/weapon/storage/box/syndie=1)
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm.rej b/code/game/gamemodes/nuclear/nuclearbomb.dm.rej
new file mode 100644
index 0000000000..6a35e91cde
--- /dev/null
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm.rej
@@ -0,0 +1,33 @@
+diff a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm (rejected hunks)
+@@ -362,9 +362,9 @@
+ if(safety)
+ if(timing)
+ set_security_level(previous_level)
+- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
++ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
+ S.switch_mode_to(initial(S.mode))
+- S.nuke_warning = FALSE
++ S.alert = FALSE
+ timing = FALSE
+ bomb_set = TRUE
+ detonation_timer = null
+@@ -381,16 +381,16 @@
+ bomb_set = TRUE
+ set_security_level("delta")
+ detonation_timer = world.time + (timer_set * 10)
+- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
++ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
+ S.switch_mode_to(TRACK_INFILTRATOR)
+ countdown.start()
+ else
+ bomb_set = FALSE
+ detonation_timer = null
+ set_security_level(previous_level)
+- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
++ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
+ S.switch_mode_to(initial(S.mode))
+- S.nuke_warning = FALSE
++ S.alert = FALSE
+ countdown.stop()
+ update_icon()
+
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index 9f63309643..342bcac090 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -60,12 +60,6 @@
msg += "\"01000001 01001001\"."
if(TRACK_INFILTRATOR)
msg += "\"vasvygengbefuvc\"."
- if(TRACK_OPERATIVES)
- msg += "\"[target ? "Operative [target]" : "friends"]\"."
- if(TRACK_ATOM)
- msg += "\"[initial(constant_target.name)]\"."
- if(TRACK_COORDINATES)
- msg += "\"([target_x], [target_y])\"."
else
msg = "Its tracking indicator is blank."
to_chat(user, msg)
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm.rej b/code/game/gamemodes/nuclear/pinpointer.dm.rej
new file mode 100644
index 0000000000..79d652af9b
--- /dev/null
+++ b/code/game/gamemodes/nuclear/pinpointer.dm.rej
@@ -0,0 +1,21 @@
+diff a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm (rejected hunks)
+@@ -30,7 +30,6 @@
+ var/mob/living/L = loc
+ to_chat(L, "Your [name] vibrates and lets out a tinny alarm. Uh oh.")
+
+-
+ /obj/item/pinpointer/nuke/scan_for_target()
+ target = null
+ switch(mode)
+@@ -58,10 +57,10 @@
+ mode = new_mode
+ scan_for_target()
+
+-
+ /obj/item/pinpointer/nuke/syndicate // Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
+ name = "syndicate pinpointer"
+ desc = "A handheld tracking device that locks onto certain signals. It's configured to switch tracking modes once it detects the activation signal of a nuclear device."
++ icon_state = "pinpointer_syndicate"
+
+ /obj/item/pinpointer/syndicate_cyborg // Cyborg pinpointers just look for a random operative.
+ name = "cyborg syndicate pinpointer"
diff --git a/code/game/gamemodes/objective_items.dm.rej b/code/game/gamemodes/objective_items.dm.rej
new file mode 100644
index 0000000000..3770d7eea9
--- /dev/null
+++ b/code/game/gamemodes/objective_items.dm.rej
@@ -0,0 +1,10 @@
+diff a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm (rejected hunks)
+@@ -158,7 +158,7 @@
+ difficulty = 10
+
+ //Old ninja objectives.
+-/datum/objective_item/special/pinpointer
++/datum/objective_item/special/pinpointer/nuke
+ name = "the captain's pinpointer."
+ targetitem = /obj/item/pinpointer
+ difficulty = 10
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 427bc95253..bf879f84da 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -869,7 +869,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/stack/medical/gauze = 8, /obj/item/reagent_containers/pill/patch/styptic = 5, /obj/item/reagent_containers/pill/insulin = 10,
/obj/item/reagent_containers/pill/patch/silver_sulf = 5, /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/spray/medical/sterilizer = 1,
/obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/salglu_solution = 3,
- /obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/device/healthanalyzer = 4, /obj/item/device/sensor_device = 2)
+ /obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/device/healthanalyzer = 4, /obj/item/device/sensor_device = 2, /obj/item/pinpointer/crew = 2)
contraband = list(/obj/item/reagent_containers/pill/tox = 3, /obj/item/reagent_containers/pill/morphine = 4, /obj/item/reagent_containers/pill/charcoal = 6)
premium = list(/obj/item/storage/box/hug/medical = 1, /obj/item/reagent_containers/hypospray/medipen = 3, /obj/item/storage/belt/medical = 3, /obj/item/wrench/medical = 1)
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
diff --git a/code/game/objects/items/devices/pinpointer.dm b/code/game/objects/items/devices/pinpointer.dm
new file mode 100644
index 0000000000..1d11f312a4
--- /dev/null
+++ b/code/game/objects/items/devices/pinpointer.dm
@@ -0,0 +1,152 @@
+//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
+/obj/item/weapon/pinpointer
+ name = "pinpointer"
+ desc = "A handheld tracking device that locks onto certain signals."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "pinpointer"
+ flags = CONDUCT
+ slot_flags = SLOT_BELT
+ w_class = WEIGHT_CLASS_SMALL
+ item_state = "electronic"
+ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
+ throw_speed = 3
+ throw_range = 7
+ materials = list(MAT_METAL = 500, MAT_GLASS = 250)
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
+ var/active = FALSE
+ var/atom/movable/target = null //The thing we're searching for
+ var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
+ var/alert = FALSE // TRUE to display things more seriously
+
+/obj/item/weapon/pinpointer/New()
+ ..()
+ GLOB.pinpointer_list += src
+
+/obj/item/weapon/pinpointer/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ GLOB.pinpointer_list -= src
+ return ..()
+
+/obj/item/weapon/pinpointer/attack_self(mob/living/user)
+ active = !active
+ user.visible_message("[user] [active ? "" : "de"]activates their pinpointer.", "You [active ? "" : "de"]activate your pinpointer.")
+ playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
+ if(active)
+ START_PROCESSING(SSfastprocess, src)
+ else
+ target = null
+ STOP_PROCESSING(SSfastprocess, src)
+ update_pointer_overlay()
+
+/obj/item/weapon/pinpointer/process()
+ if(!active)
+ STOP_PROCESSING(SSfastprocess, src)
+ return
+ scan_for_target()
+ update_pointer_overlay()
+
+/obj/item/weapon/pinpointer/proc/scan_for_target()
+ return
+
+/obj/item/weapon/pinpointer/proc/update_pointer_overlay()
+ cut_overlays()
+ if(!active)
+ return
+ if(!target)
+ add_overlay("pinon[alert ? "alert" : ""]null")
+ var/turf/here = get_turf(src)
+ var/turf/there = get_turf(target)
+ if(here.z != there.z)
+ add_overlay("pinon[alert ? "alert" : ""]null")
+ return
+ if(get_dist_euclidian(here,there) <= minimum_range)
+ add_overlay("pinon[alert ? "alert" : ""]direct")
+ else
+ setDir(get_dir(here, there))
+ switch(get_dist(here, there))
+ if(1 to 8)
+ add_overlay("pinon[alert ? "alert" : "close"]")
+ if(9 to 16)
+ add_overlay("pinon[alert ? "alert" : "medium"]")
+ if(16 to INFINITY)
+ add_overlay("pinon[alert ? "alert" : "far"]")
+
+/obj/item/weapon/pinpointer/crew // A replacement for the old crew monitoring consoles
+ name = "crew pinpointer"
+ desc = "A handheld tracking device that points to crew suit sensors."
+ icon_state = "pinpointer_crew"
+
+/obj/item/weapon/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
+ var/turf/here = get_turf(src)
+ if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
+ var/obj/item/clothing/under/U = H.w_uniform
+
+ // Suit sensors must be on maximum.
+ if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
+ return FALSE
+
+ var/turf/there = get_turf(H)
+ return (H.z != 0 || (there && there.z == H.z))
+
+ return FALSE
+
+/obj/item/weapon/pinpointer/crew/attack_self(mob/living/user)
+ if(active)
+ active = FALSE
+ user.visible_message("[user] deactivates their pinpointer.", "You deactivate your pinpointer.")
+ playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
+ target = null //Restarting the pinpointer forces a target reset
+ STOP_PROCESSING(SSfastprocess, src)
+ update_pointer_overlay()
+ return
+
+ var/list/name_counts = list()
+ var/list/names = list()
+
+ for(var/mob/living/carbon/human/H in GLOB.mob_list)
+ if(!trackable(H))
+ continue
+
+ var/name = "Unknown"
+ if(H.wear_id)
+ var/obj/item/weapon/card/id/I = H.wear_id.GetID()
+ name = I.registered_name
+
+ while(name in name_counts)
+ name_counts[name]++
+ name = text("[] ([])", name, name_counts[name])
+ names[name] = H
+ name_counts[name] = 1
+
+ if(!names.len)
+ user.visible_message("[user]'s pinpointer fails to detect a signal.", "Your pinpointer fails to detect a signal.")
+ return
+
+ var/A = input(user, "Person to track", "Pinpoint") in names
+ if(!src || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !A)
+ return
+
+ target = names[A]
+ active = TRUE
+ user.visible_message("[user] activates their pinpointer.", "You activate your pinpointer.")
+ playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
+ START_PROCESSING(SSfastprocess, src)
+ update_pointer_overlay()
+
+/obj/item/weapon/pinpointer/crew/scan_for_target()
+ if(target)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(!trackable(H))
+ target = null
+ if(!target)
+ active = FALSE
+
+/obj/item/weapon/pinpointer/process()
+ if(!active)
+ STOP_PROCESSING(SSfastprocess, src)
+ return
+ scan_for_target()
+ update_pointer_overlay()
+
diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm
new file mode 100644
index 0000000000..28488a231f
--- /dev/null
+++ b/code/game/objects/items/pinpointer.dm
@@ -0,0 +1,150 @@
+//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
+/obj/item/pinpointer
+ name = "pinpointer"
+ desc = "A handheld tracking device that locks onto certain signals."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "pinpointer"
+ flags_1 = CONDUCT_1
+ slot_flags = SLOT_BELT
+ w_class = WEIGHT_CLASS_SMALL
+ item_state = "electronic"
+ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
+ throw_speed = 3
+ throw_range = 7
+ materials = list(MAT_METAL = 500, MAT_GLASS = 250)
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
+ var/active = FALSE
+ var/atom/movable/target //The thing we're searching for
+ var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
+ var/alert = FALSE // TRUE to display things more seriously
+
+/obj/item/pinpointer/Initialize()
+ . = ..()
+ GLOB.pinpointer_list += src
+
+/obj/item/pinpointer/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ GLOB.pinpointer_list -= src
+ return ..()
+
+/obj/item/pinpointer/attack_self(mob/living/user)
+ active = !active
+ user.visible_message("[user] [active ? "" : "de"]activates their pinpointer.", "You [active ? "" : "de"]activate your pinpointer.")
+ playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
+ if(active)
+ START_PROCESSING(SSfastprocess, src)
+ else
+ target = null
+ STOP_PROCESSING(SSfastprocess, src)
+ update_icon()
+
+/obj/item/pinpointer/process()
+ if(!active)
+ return PROCESS_KILL
+ scan_for_target()
+ update_icon()
+
+/obj/item/pinpointer/proc/scan_for_target()
+ return
+
+/obj/item/pinpointer/update_icon()
+ cut_overlays()
+ if(!active)
+ return
+ if(!target)
+ add_overlay("pinon[alert ? "alert" : ""]null")
+ var/turf/here = get_turf(src)
+ var/turf/there = get_turf(target)
+ if(here.z != there.z)
+ add_overlay("pinon[alert ? "alert" : ""]null")
+ return
+ if(get_dist_euclidian(here,there) <= minimum_range)
+ add_overlay("pinon[alert ? "alert" : ""]direct")
+ else
+ setDir(get_dir(here, there))
+ switch(get_dist(here, there))
+ if(1 to 8)
+ add_overlay("pinon[alert ? "alert" : "close"]")
+ if(9 to 16)
+ add_overlay("pinon[alert ? "alert" : "medium"]")
+ if(16 to INFINITY)
+ add_overlay("pinon[alert ? "alert" : "far"]")
+
+/obj/item/pinpointer/crew // A replacement for the old crew monitoring consoles
+ name = "crew pinpointer"
+ desc = "A handheld tracking device that points to crew suit sensors."
+ icon_state = "pinpointer_crew"
+
+/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
+ var/turf/here = get_turf(src)
+ if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
+ var/obj/item/clothing/under/U = H.w_uniform
+
+ // Suit sensors must be on maximum.
+ if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
+ return FALSE
+
+ var/turf/there = get_turf(H)
+ return (H.z != 0 || (there && there.z == H.z))
+
+ return FALSE
+
+/obj/item/pinpointer/crew/attack_self(mob/living/user)
+ if(active)
+ active = FALSE
+ user.visible_message("[user] deactivates their pinpointer.", "You deactivate your pinpointer.")
+ playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
+ target = null //Restarting the pinpointer forces a target reset
+ STOP_PROCESSING(SSfastprocess, src)
+ update_icon()
+ return
+
+ var/list/name_counts = list()
+ var/list/names = list()
+
+ for(var/mob/living/carbon/human/H in GLOB.mob_list)
+ if(!trackable(H))
+ continue
+
+ var/crewmember_name = "Unknown"
+ if(H.wear_id)
+ var/obj/item/card/id/I = H.wear_id.GetID()
+ crewmember_name = I.registered_name
+
+ while(crewmember_name in name_counts)
+ name_counts[crewmember_name]++
+ crewmember_name = text("[] ([])", crewmember_name, name_counts[crewmember_name])
+ names[crewmember_name] = H
+ name_counts[crewmember_name] = 1
+
+ if(!names.len)
+ user.visible_message("[user]'s pinpointer fails to detect a signal.", "Your pinpointer fails to detect a signal.")
+ return
+
+ var/A = input(user, "Person to track", "Pinpoint") in names
+ if(!A || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated())
+ return
+
+ target = names[A]
+ active = TRUE
+ user.visible_message("[user] activates their pinpointer.", "You activate your pinpointer.")
+ playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
+ START_PROCESSING(SSfastprocess, src)
+ update_icon()
+
+/obj/item/pinpointer/crew/scan_for_target()
+ if(target)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(!trackable(H))
+ target = null
+ if(!target) //target can be set to null from above code, or elsewhere
+ active = FALSE
+
+/obj/item/pinpointer/process()
+ if(!active)
+ return PROCESS_KILL
+ scan_for_target()
+ update_icon()
+
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 6327d2d3ff..f13eaf73c4 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -83,7 +83,7 @@
new /obj/item/storage/belt/security/full(src)
new /obj/item/gun/energy/e_gun/hos(src)
new /obj/item/device/flashlight/seclite(src)
- new /obj/item/pinpointer(src)
+ new /obj/item/pinpointer/nuke(src)
/obj/structure/closet/secure_closet/warden
name = "\proper warden's locker"
@@ -108,6 +108,7 @@
new /obj/item/clothing/gloves/krav_maga/sec(src)
new /obj/item/door_remote/head_of_security(src)
new /obj/item/gun/ballistic/shotgun/automatic/combat/compact(src)
+ new /obj/item/pinpointer/crew(src)
/obj/structure/closet/secure_closet/security
name = "security officer's locker"
@@ -183,6 +184,7 @@
new /obj/item/reagent_containers/spray/pepper(src)
new /obj/item/clothing/suit/armor/vest/det_suit(src)
new /obj/item/storage/belt/holster/full(src)
+ new /obj/item/pinpointer/crew(src)
/obj/structure/closet/secure_closet/injection
name = "lethal injections"
diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm
index 7301724eb6..abb87a4235 100644
--- a/code/modules/admin/verbs/onlyone.dm
+++ b/code/modules/admin/verbs/onlyone.dm
@@ -50,8 +50,8 @@ GLOBAL_VAR_INIT(highlander, FALSE)
equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(src), slot_ears)
equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(src), slot_head)
equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(src), slot_shoes)
- equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_l_store)
- for(var/obj/item/pinpointer/P in src)
+ equip_to_slot_or_del(new /obj/item/pinpointer/nuke(src), slot_l_store)
+ for(var/obj/item/pinpointer/nuke/P in src)
P.attack_self(src)
var/obj/item/card/id/W = new(src)
W.icon_state = "centcom"
diff --git a/code/modules/jobs/job_types/medical.dm b/code/modules/jobs/job_types/medical.dm
index 5f22e1886a..3d9f857dbf 100644
--- a/code/modules/jobs/job_types/medical.dm
+++ b/code/modules/jobs/job_types/medical.dm
@@ -30,6 +30,7 @@ Chief Medical Officer
id = /obj/item/card/id/silver
belt = /obj/item/device/pda/heads/cmo
+ l_pocket = /obj/item/pinpointer/crew
ears = /obj/item/device/radio/headset/heads/cmo
uniform = /obj/item/clothing/under/rank/chief_medical_officer
shoes = /obj/item/clothing/shoes/sneakers/brown
diff --git a/code/modules/mob/living/silicon/ai/death.dm.rej b/code/modules/mob/living/silicon/ai/death.dm.rej
new file mode 100644
index 0000000000..40b5625e8c
--- /dev/null
+++ b/code/modules/mob/living/silicon/ai/death.dm.rej
@@ -0,0 +1,13 @@
+diff a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm (rejected hunks)
+@@ -35,9 +35,9 @@
+ if(nuking)
+ set_security_level("red")
+ nuking = FALSE
+- for(var/obj/item/weapon/pinpointer/P in GLOB.pinpointer_list)
++ for(var/obj/item/weapon/pinpointer/nuke/P in GLOB.pinpointer_list)
+ P.switch_mode_to(TRACK_NUKE_DISK) //Party's over, back to work, everyone
+- P.nuke_warning = FALSE
++ P.alert = FALSE
+
+ if(doomsday_device)
+ doomsday_device.timing = FALSE
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm.rej b/code/modules/mob/living/silicon/robot/robot_modules.dm.rej
new file mode 100644
index 0000000000..b0f0812dc4
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm.rej
@@ -0,0 +1,19 @@
+diff a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm (rejected hunks)
+@@ -519,7 +519,7 @@
+ /obj/item/weapon/gun/ballistic/revolver/grenadelauncher/cyborg,
+ /obj/item/weapon/card/emag,
+ /obj/item/weapon/crowbar/cyborg,
+- /obj/item/weapon/pinpointer/syndicate/cyborg)
++ /obj/item/weapon/pinpointer/syndicate_cyborg)
+
+ ratvar_modules = list(
+ /obj/item/clockwork/slab/cyborg/security,
+@@ -545,7 +545,7 @@
+ /obj/item/roller/robo,
+ /obj/item/weapon/card/emag,
+ /obj/item/weapon/crowbar/cyborg,
+- /obj/item/weapon/pinpointer/syndicate/cyborg,
++ /obj/item/weapon/pinpointer/syndicate_cyborg,
+ /obj/item/stack/medical/gauze/cyborg,
+ /obj/item/weapon/gun/medbeam)
+ ratvar_modules = list(
diff --git a/code/modules/power/apc.dm.rej b/code/modules/power/apc.dm.rej
new file mode 100644
index 0000000000..9e432f503c
--- /dev/null
+++ b/code/modules/power/apc.dm.rej
@@ -0,0 +1,13 @@
+diff a/code/modules/power/apc.dm b/code/modules/power/apc.dm (rejected hunks)
+@@ -867,9 +867,9 @@
+ occupier.loc = src.loc
+ occupier.death()
+ occupier.gib()
+- for(var/obj/item/weapon/pinpointer/P in GLOB.pinpointer_list)
++ for(var/obj/item/weapon/pinpointer/nuke/P in GLOB.pinpointer_list)
+ P.switch_mode_to(TRACK_NUKE_DISK) //Pinpointers go back to tracking the nuke disk
+- P.nuke_warning = FALSE
++ P.alert = FALSE
+
+ /obj/machinery/power/apc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
+ if(card.AI)
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 808de69446..79f0a207d4 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 1e1c153493..4c2da1f48b 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -793,6 +793,7 @@
#include "code\game\objects\items\mop.dm"
#include "code\game\objects\items\paint.dm"
#include "code\game\objects\items\paiwire.dm"
+#include "code\game\objects\items\pinpointer.dm"
#include "code\game\objects\items\pneumaticCannon.dm"
#include "code\game\objects\items\powerfist.dm"
#include "code\game\objects\items\RCD.dm"
diff --git a/tgstation.dme.rej b/tgstation.dme.rej
index a5ff4dc3cb..82c613607a 100644
--- a/tgstation.dme.rej
+++ b/tgstation.dme.rej
@@ -1,13 +1,9 @@
diff a/tgstation.dme b/tgstation.dme (rejected hunks)
-@@ -1746,6 +1745,11 @@
- #include "code\modules\mob\living\simple_animal\hostile\gorilla\emotes.dm"
- #include "code\modules\mob\living\simple_animal\hostile\gorilla\gorilla.dm"
- #include "code\modules\mob\living\simple_animal\hostile\gorilla\visuals_icons.dm"
-+#include "code\modules\mob\living\simple_animal\hostile\jungle\_jungle_mobs.dm"
-+#include "code\modules\mob\living\simple_animal\hostile\jungle\leaper.dm"
-+#include "code\modules\mob\living\simple_animal\hostile\jungle\mega_arachnid.dm"
-+#include "code\modules\mob\living\simple_animal\hostile\jungle\mook.dm"
-+#include "code\modules\mob\living\simple_animal\hostile\jungle\seedling.dm"
- #include "code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm"
- #include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm"
- #include "code\modules\mob\living\simple_animal\hostile\megafauna\colossus.dm"
+@@ -793,7 +794,6 @@
+ #include "code\game\objects\items\devices\megaphone.dm"
+ #include "code\game\objects\items\devices\multitool.dm"
+ #include "code\game\objects\items\devices\paicard.dm"
+-#include "code\game\objects\items\devices\pinpointer.dm"
+ #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"