diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index f6e454bd737..2cb7f9fcd50 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -1,3 +1,14 @@
+#define MODE_OFF 0
+#define MODE_DISK 1
+#define MODE_NUKE 2
+#define MODE_ADV 3
+#define MODE_SHIP 4
+#define MODE_OPERATIVE 5
+#define MODE_CREW 6
+#define SETTING_DISK 0
+#define SETTING_LOCATION 1
+#define SETTING_OBJECT 2
+
/obj/item/pinpointer
name = "pinpointer"
icon = 'icons/obj/device.dmi'
@@ -11,8 +22,13 @@
materials = list(MAT_METAL=500)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/obj/item/disk/nuclear/the_disk = null
- var/active = 0
+ var/obj/machinery/nuclearbomb/the_bomb = null
+ var/obj/machinery/nuclearbomb/syndicate/the_s_bomb = null // used by syndicate pinpointers.
+ var/cur_index = 1 // Which index the current mode is
+ var/mode = MODE_OFF // On which mode the pointer is at
+ var/modes = list(MODE_DISK, MODE_NUKE) // Which modes are there
var/shows_nuke_timer = TRUE
+ var/syndicate = FALSE // Indicates pointer is syndicate, and points to the syndicate nuke.
var/icon_off = "pinoff"
var/icon_null = "pinonnull"
var/icon_direct = "pinondirect"
@@ -25,28 +41,66 @@
GLOB.pinpointer_list += src
/obj/item/pinpointer/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
GLOB.pinpointer_list -= src
- active = 0
+ mode = MODE_OFF
the_disk = null
return ..()
-/obj/item/pinpointer/attack_self()
- if(!active)
- active = 1
+/obj/item/pinpointer/process()
+ if(mode == MODE_DISK)
workdisk()
- to_chat(usr, "You activate the pinpointer.")
- else
- active = 0
+ else if(mode == MODE_NUKE)
+ workbomb()
+
+/obj/item/pinpointer/attack_self(mob/user)
+ cycle(user)
+
+/obj/item/pinpointer/proc/cycle(mob/user)
+ if(cur_index > length(modes))
+ mode = MODE_OFF
+ to_chat(user, "You deactivate [src].")
+ STOP_PROCESSING(SSfastprocess, src)
icon_state = icon_off
- to_chat(usr, "You deactivate the pinpointer.")
+ cur_index = 1
+ return
+ if(cur_index == 1)
+ START_PROCESSING(SSfastprocess, src)
+ mode = modes[cur_index++]
+ activate_mode(mode, user)
+ to_chat(user, "[get_mode_text(mode)]")
+
+/obj/item/pinpointer/proc/get_mode_text(mode)
+ switch(mode)
+ if(MODE_DISK)
+ return "Authentication Disk Locator active."
+ if(MODE_NUKE)
+ return "Nuclear Device Locator active."
+ if(MODE_ADV)
+ return "Advanced Pinpointer Online."
+ if(MODE_SHIP)
+ return "Shuttle Locator active."
+ if(MODE_OPERATIVE)
+ return "You point the pinpointer to the nearest operative."
+ if(MODE_CREW)
+ return "You turn on the pinpointer."
+
+/obj/item/pinpointer/proc/activate_mode(mode, mob/user) //for crew pinpointer
+ return
/obj/item/pinpointer/proc/scandisk()
if(!the_disk)
the_disk = locate()
-/obj/item/pinpointer/proc/point_at(atom/target, spawnself = 1)
- if(!active)
- return
+/obj/item/pinpointer/proc/scanbomb()
+ if(!syndicate)
+ if(!the_bomb)
+ the_bomb = locate()
+ else
+ if(!the_s_bomb)
+ the_s_bomb = locate()
+
+/obj/item/pinpointer/proc/point_at(atom/target)
if(!target)
icon_state = icon_null
return
@@ -67,15 +121,18 @@
icon_state = icon_medium
if(16 to INFINITY)
icon_state = icon_far
- if(spawnself)
- spawn(5)
- .()
/obj/item/pinpointer/proc/workdisk()
scandisk()
- point_at(the_disk, 0)
- spawn(5)
- .()
+ point_at(the_disk)
+
+/obj/item/pinpointer/proc/workbomb()
+ if(!syndicate)
+ scanbomb()
+ point_at(the_bomb)
+ else
+ scanbomb()
+ point_at(the_s_bomb)
/obj/item/pinpointer/examine(mob/user)
. = ..()
@@ -87,32 +144,24 @@
/obj/item/pinpointer/advpinpointer
name = "advanced pinpointer"
desc = "A larger version of the normal pinpointer, this unit features a helpful quantum entanglement detection system to locate various objects that do not broadcast a locator signal."
- var/mode = 0 // Mode 0 locates disk, mode 1 locates coordinates.
+ modes = list(MODE_ADV)
var/modelocked = FALSE // If true, user cannot change mode.
var/turf/location = null
var/obj/target = null
+ var/setting = 0
-/obj/item/pinpointer/advpinpointer/attack_self()
- if(!active)
- active = 1
- if(mode == 0)
+/obj/item/pinpointer/advpinpointer/process()
+ switch(setting)
+ if(SETTING_DISK)
workdisk()
- if(mode == 1)
+ if(SETTING_LOCATION)
point_at(location)
- if(mode == 2)
+ if(SETTING_OBJECT)
point_at(target)
- to_chat(usr, "You activate the pinpointer.")
- else
- active = 0
- icon_state = icon_off
- to_chat(usr, "You deactivate the pinpointer.")
-/obj/item/pinpointer/advpinpointer/workdisk()
- if(mode == 0)
- scandisk()
- point_at(the_disk, 0)
- spawn(5)
- .()
+/obj/item/pinpointer/advpinpointer/workdisk() //since mode works diffrently for advpinpointer
+ scandisk()
+ point_at(the_disk)
/obj/item/pinpointer/advpinpointer/verb/toggle_mode()
set category = "Object"
@@ -126,14 +175,14 @@
to_chat(usr, "[src] is locked. It can only track one specific target.")
return
- active = 0
+ mode = MODE_OFF
icon_state = icon_off
target = null
location = null
switch(alert("Please select the mode you want to put the pinpointer in.", "Pinpointer Mode Select", "Location", "Disk Recovery", "Other Signature"))
if("Location")
- mode = 1
+ setting = SETTING_LOCATION
var/locationx = input(usr, "Please input the x coordinate to search for.", "Location?" , "") as num
if(!locationx || !(usr in view(1,src)))
@@ -152,11 +201,11 @@
return attack_self()
if("Disk Recovery")
- mode = 0
+ setting = SETTING_DISK
return attack_self()
if("Other Signature")
- mode = 2
+ setting = SETTING_OBJECT
switch(alert("Search for item signature or DNA fragment?" , "Signature Mode Select" , "Item" , "DNA"))
if("Item")
var/list/item_names[0]
@@ -197,61 +246,44 @@
//nuke op pinpointers//
///////////////////////
/obj/item/pinpointer/nukeop
- var/mode = 0 //Mode 0 locates disk, mode 1 locates the shuttle
var/obj/docking_port/mobile/home = null
slot_flags = SLOT_BELT | SLOT_PDA
+ syndicate = TRUE
+ modes = list(MODE_DISK, MODE_NUKE)
-/obj/item/pinpointer/nukeop/attack_self(mob/user as mob)
- if(!active)
- active = 1
- if(!mode)
+/obj/item/pinpointer/nukeop/process()
+ switch(mode)
+ if(MODE_DISK)
workdisk()
- to_chat(user, "Authentication Disk Locator active.")
- else
+ if(MODE_NUKE)
+ workbomb()
+ if(MODE_SHIP)
worklocation()
- to_chat(user, "Shuttle Locator active.")
- else
- active = 0
- icon_state = icon_off
- to_chat(user, "You deactivate the pinpointer.")
/obj/item/pinpointer/nukeop/workdisk()
- if(!active) return
- if(mode) //Check in case the mode changes while operating
- worklocation()
- return
if(GLOB.bomb_set) //If the bomb is set, lead to the shuttle
- mode = 1 //Ensures worklocation() continues to work
- worklocation()
+ mode = MODE_SHIP //Ensures worklocation() continues to work
+ modes = list(MODE_SHIP)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep
visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed
return //Get outta here
scandisk()
- if(!the_disk)
- icon_state = icon_null
- return
- dir = get_dir(src, the_disk)
- switch(get_dist(src, the_disk))
- if(0)
- icon_state = icon_direct
- if(1 to 8)
- icon_state = icon_close
- if(9 to 16)
- icon_state = icon_medium
- if(16 to INFINITY)
- icon_state = icon_far
+ point_at(the_disk)
- spawn(5) .()
+/obj/item/pinpointer/nukeop/workbomb()
+ if(GLOB.bomb_set) //If the bomb is set, lead to the shuttle
+ mode = MODE_SHIP //Ensures worklocation() continues to work
+ modes = list(MODE_SHIP)
+ playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep
+ visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed
+ return //Get outta here
+ scanbomb()
+ point_at(the_s_bomb)
/obj/item/pinpointer/nukeop/proc/worklocation()
- if(!active)
- return
- if(!mode)
- workdisk()
- return
if(!GLOB.bomb_set)
- mode = 0
- workdisk()
+ mode = MODE_DISK
+ modes = list(MODE_DISK, MODE_NUKE)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
visible_message("Authentication Disk Locator mode actived.")
return
@@ -263,40 +295,22 @@
if(loc.z != home.z) //If you are on a different z-level from the shuttle
icon_state = icon_null
else
- dir = get_dir(src, home)
- switch(get_dist(src, home))
- if(0)
- icon_state = icon_direct
- if(1 to 8)
- icon_state = icon_close
- if(9 to 16)
- icon_state = icon_medium
- if(16 to INFINITY)
- icon_state = icon_far
-
- spawn(5)
- .()
+ point_at(home)
/obj/item/pinpointer/operative
name = "operative pinpointer"
desc = "A pinpointer that leads to the first Syndicate operative detected."
var/mob/living/carbon/nearest_op = null
+ modes = list(MODE_OPERATIVE)
-/obj/item/pinpointer/operative/attack_self()
- if(!usr.mind || !(usr.mind in SSticker.mode.syndicates))
- to_chat(usr, "AUTHENTICATION FAILURE. ACCESS DENIED.")
- return 0
- if(!active)
- active = 1
+/obj/item/pinpointer/operative/process()
+ if(mode == MODE_OPERATIVE)
workop()
- to_chat(usr, "You activate the pinpointer.")
else
- active = 0
icon_state = icon_off
- to_chat(usr, "You deactivate the pinpointer.")
/obj/item/pinpointer/operative/proc/scan_for_ops()
- if(active)
+ if(mode == MODE_OPERATIVE)
nearest_op = null //Resets nearest_op every time it scans
var/closest_distance = 1000
for(var/mob/living/carbon/M in GLOB.mob_list)
@@ -305,17 +319,15 @@
nearest_op = M
/obj/item/pinpointer/operative/proc/workop()
- if(active)
+ if(mode == MODE_OPERATIVE)
scan_for_ops()
- point_at(nearest_op, 0)
- spawn(5)
- .()
+ point_at(nearest_op, FALSE)
else
- return 0
+ return FALSE
/obj/item/pinpointer/operative/examine(mob/user)
. = ..()
- if(active)
+ if(mode == MODE_OPERATIVE)
if(nearest_op)
. += "Nearest operative detected is [nearest_op.real_name]."
else
@@ -332,6 +344,9 @@
icon_close = "pinonclose_crew"
icon_medium = "pinonmedium_crew"
icon_far = "pinonfar_crew"
+ modes = list(MODE_CREW)
+ var/target = null //for targeting in processing
+ var/target_set = FALSE //have we set a target at any point?
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
var/turf/here = get_turf(src)
@@ -347,13 +362,18 @@
return FALSE
-/obj/item/pinpointer/crew/attack_self(mob/living/user)
- if(active)
- active = FALSE
- icon_state = icon_off
- user.visible_message("[user] deactivates [user.p_their()] pinpointer.", "You deactivate your pinpointer.")
+/obj/item/pinpointer/crew/process()
+ if(mode == MODE_CREW && target_set)
+ point_at(target)
+
+/obj/item/pinpointer/crew/point_at(atom/target)
+ if(!trackable(target) || !target)
+ icon_state = icon_null
return
+ ..(target)
+
+/obj/item/pinpointer/crew/activate_mode(mode, mob/user)
var/list/name_counts = list()
var/list/names = list()
@@ -382,23 +402,9 @@
if(!src || !user || (user.get_active_hand() != src) || user.incapacitated() || !A)
return
- var/target = names[A]
- active = TRUE
+ target = names[A]
+ target_set = TRUE
user.visible_message("[user] activates [user.p_their()] pinpointer.", "You activate your pinpointer.")
- point_at(target)
-
-/obj/item/pinpointer/crew/point_at(atom/target, spawnself = 1)
- if(!active)
- return
-
- if(!trackable(target) || !target)
- icon_state = icon_null
- return
-
- ..(target, spawnself = 0)
- if(spawnself)
- spawn(5)
- .()
/obj/item/pinpointer/crew/centcom
name = "centcom pinpointer"
@@ -408,3 +414,14 @@
var/turf/here = get_turf(src)
var/turf/there = get_turf(H)
return there && there.z == here.z
+
+#undef MODE_OFF
+#undef MODE_DISK
+#undef MODE_NUKE
+#undef MODE_ADV
+#undef MODE_SHIP
+#undef MODE_OPERATIVE
+#undef MODE_CREW
+#undef SETTING_DISK
+#undef SETTING_LOCATION
+#undef SETTING_OBJECT
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index f56ec0fa7fa..ed961e83337 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -3417,8 +3417,8 @@
hunter_mob.equipOutfit(O, FALSE)
var/obj/item/pinpointer/advpinpointer/N = new /obj/item/pinpointer/advpinpointer(hunter_mob)
hunter_mob.equip_to_slot_or_del(N, slot_in_backpack)
- N.active = 1
- N.mode = 2
+ N.mode = 3 //MODE_ADV, not defined here
+ N.setting = 2 //SETTING_OBJECT, not defined here
N.target = H
N.point_at(N.target)
N.modelocked = TRUE