//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") return 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() if(I && I.registered_name) 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()