diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index a38ccf59ca..b2bd6b80e4 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -12,45 +12,51 @@
var/obj/item/weapon/disk/nuclear/the_disk = null
var/active = 0
-
- attack_self()
- if(!active)
- active = 1
- workdisk()
- to_chat(usr, "You activate the pinpointer")
- else
- active = 0
- icon_state = "pinoff"
- to_chat(usr, "You deactivate the pinpointer")
-
- proc/workdisk()
- if(!active) return
- if(!the_disk)
- the_disk = locate()
- if(!the_disk)
- icon_state = "pinonnull"
- return
- set_dir(get_dir(src,the_disk))
- switch(get_dist(src,the_disk))
- if(0)
- icon_state = "pinondirect"
- if(1 to 8)
- icon_state = "pinonclose"
- if(9 to 16)
- icon_state = "pinonmedium"
- if(16 to INFINITY)
- icon_state = "pinonfar"
- spawn(5) .()
-
- examine(mob/user)
- ..(user)
- for(var/obj/machinery/nuclearbomb/bomb in machines)
- if(bomb.timing)
- to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]")
-
/obj/item/weapon/pinpointer/Destroy()
active = 0
- ..()
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/weapon/pinpointer/attack_self()
+ if(!active)
+ active = 1
+ START_PROCESSING(SSobj, src)
+ to_chat(usr, "You activate the pinpointer")
+ else
+ active = 0
+ STOP_PROCESSING(SSobj, src)
+ icon_state = "pinoff"
+ to_chat(usr, "You deactivate the pinpointer")
+
+/obj/item/weapon/pinpointer/process()
+ if(!active)
+ return PROCESS_KILL
+
+ if(!the_disk)
+ the_disk = locate()
+ if(!the_disk)
+ icon_state = "pinonnull"
+ return
+
+ set_dir(get_dir(src,the_disk))
+
+ switch(get_dist(src,the_disk))
+ if(0)
+ icon_state = "pinondirect"
+ if(1 to 8)
+ icon_state = "pinonclose"
+ if(9 to 16)
+ icon_state = "pinonmedium"
+ if(16 to INFINITY)
+ icon_state = "pinonfar"
+
+/obj/item/weapon/pinpointer/examine(mob/user)
+ ..(user)
+ for(var/obj/machinery/nuclearbomb/bomb in machines)
+ if(bomb.timing)
+ to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]")
+
+
/obj/item/weapon/pinpointer/advpinpointer
name = "Advanced Pinpointer"
@@ -60,58 +66,49 @@
var/turf/location = null
var/obj/target = null
- attack_self()
- if(!active)
- active = 1
- if(mode == 0)
- workdisk()
- if(mode == 1)
- worklocation()
- if(mode == 2)
- workobj()
- to_chat(usr, "You activate the pinpointer")
- else
- active = 0
- icon_state = "pinoff"
- to_chat(usr, "You deactivate the pinpointer")
+/obj/item/weapon/pinpointer/advpinpointer/process()
+ if(!active)
+ return PROCESS_KILL
+ if(mode == 0)
+ ..()
+ if(mode == 1)
+ worklocation()
+ if(mode == 2)
+ workobj()
+/obj/item/weapon/pinpointer/advpinpointer/proc/worklocation()
+ if(!location)
+ icon_state = "pinonnull"
+ return
- proc/worklocation()
- if(!active)
- return
- if(!location)
- icon_state = "pinonnull"
- return
- set_dir(get_dir(src,location))
- switch(get_dist(src,location))
- if(0)
- icon_state = "pinondirect"
- if(1 to 8)
- icon_state = "pinonclose"
- if(9 to 16)
- icon_state = "pinonmedium"
- if(16 to INFINITY)
- icon_state = "pinonfar"
- spawn(5) .()
+ set_dir(get_dir(src,location))
+ switch(get_dist(src,location))
+ if(0)
+ icon_state = "pinondirect"
+ if(1 to 8)
+ icon_state = "pinonclose"
+ if(9 to 16)
+ icon_state = "pinonmedium"
+ if(16 to INFINITY)
+ icon_state = "pinonfar"
- proc/workobj()
- if(!active)
- return
- if(!target)
- icon_state = "pinonnull"
- return
- set_dir(get_dir(src,target))
- switch(get_dist(src,target))
- if(0)
- icon_state = "pinondirect"
- if(1 to 8)
- icon_state = "pinonclose"
- if(9 to 16)
- icon_state = "pinonmedium"
- if(16 to INFINITY)
- icon_state = "pinonfar"
- spawn(5) .()
+/obj/item/weapon/pinpointer/advpinpointer/proc/workobj()
+ if(!target)
+ icon_state = "pinonnull"
+ return
+
+ set_dir(get_dir(src,target))
+
+ switch(get_dist(src,target))
+ if(0)
+ icon_state = "pinondirect"
+ if(1 to 8)
+ icon_state = "pinonclose"
+ if(9 to 16)
+ icon_state = "pinonmedium"
+ if(16 to INFINITY)
+ icon_state = "pinonfar"
/obj/item/weapon/pinpointer/advpinpointer/verb/toggle_mode()
set category = "Object"
@@ -140,7 +137,6 @@
to_chat(usr, "You set the pinpointer to locate [locationx],[locationy]")
-
return attack_self()
if("Disk Recovery")
@@ -150,9 +146,10 @@
if("Other Signature")
mode = 2
switch(alert("Search for item signature or DNA fragment?" , "Signature Mode Select" , "" , "Item" , "DNA"))
+
if("Item")
var/datum/objective/steal/itemlist
- itemlist = itemlist // To supress a 'variable defined but not used' error.
+ itemlist = itemlist
var/targetitem = input("Select item to search for.", "Item Mode Select","") as null|anything in itemlist.possible_items
if(!targetitem)
return
@@ -161,6 +158,7 @@
to_chat(usr, "Failed to locate [targetitem]!")
return
to_chat(usr, "You set the pinpointer to locate [targetitem]")
+
if("DNA")
var/DNAstring = input("Input DNA string to search for." , "Please Enter String." , "")
if(!DNAstring)
@@ -187,6 +185,7 @@
/obj/item/weapon/pinpointer/nukeop/attack_self(mob/user as mob)
if(!active)
active = 1
+ START_PROCESSING(SSobj, src)
if(!mode)
workdisk()
to_chat(user, "Authentication Disk Locator active.")
@@ -195,30 +194,35 @@
to_chat(user, "Shuttle Locator active.")
else
active = 0
+ STOP_PROCESSING(SSobj, src)
icon_state = "pinoff"
to_chat(user, "You deactivate the pinpointer.")
+/obj/item/weapon/pinpointer/nukeop/process()
+ if(!active)
+ return PROCESS_KILL
-/obj/item/weapon/pinpointer/nukeop/workdisk()
- if(!active) return
- if(mode) //Check in case the mode changes while operating
- worklocation()
- return
+ switch(mode)
+ if(0)
+ workdisk()
+ if(1)
+ worklocation()
+
+/obj/item/weapon/pinpointer/nukeop/proc/workdisk()
if(bomb_set) //If the bomb is set, lead to the shuttle
mode = 1 //Ensures worklocation() continues to work
- worklocation()
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep
- visible_message("Shuttle Locator active.") //Lets the mob holding it know that the mode has changed
+ visible_message("Shuttle Locator active.") //Lets the mob holding it know that the mode has changed
return //Get outta here
+
if(!the_disk)
the_disk = locate()
if(!the_disk)
icon_state = "pinonnull"
return
-// if(loc.z != the_disk.z) //If you are on a different z-level from the disk
-// icon_state = "pinonnull"
-// else
+
set_dir(get_dir(src, the_disk))
+
switch(get_dist(src, the_disk))
if(0)
icon_state = "pinondirect"
@@ -229,29 +233,25 @@
if(16 to INFINITY)
icon_state = "pinonfar"
- spawn(5) .()
-
-
/obj/item/weapon/pinpointer/nukeop/proc/worklocation()
- if(!active) return
- if(!mode)
- workdisk()
- return
if(!bomb_set)
mode = 0
- workdisk()
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
visible_message("Authentication Disk Locator active.")
return
+
if(!home)
home = locate()
if(!home)
icon_state = "pinonnull"
return
+
if(loc.z != home.z) //If you are on a different z-level from the shuttle
icon_state = "pinonnull"
+
else
set_dir(get_dir(src, home))
+
switch(get_dist(src, home))
if(0)
icon_state = "pinondirect"
@@ -262,8 +262,6 @@
if(16 to INFINITY)
icon_state = "pinonfar"
- spawn(5) .()
-
// This one only points to the ship. Useful if there is no nuking to occur today.
/obj/item/weapon/pinpointer/shuttle
@@ -273,16 +271,17 @@
/obj/item/weapon/pinpointer/shuttle/attack_self(mob/user as mob)
if(!active)
active = TRUE
- find_shuttle()
+ START_PROCESSING(SSobj, src)
to_chat(user, "Shuttle Locator active.")
else
active = FALSE
+ STOP_PROCESSING(SSobj, src)
icon_state = "pinoff"
to_chat(user, "You deactivate the pinpointer.")
-/obj/item/weapon/pinpointer/shuttle/proc/find_shuttle()
+/obj/item/weapon/pinpointer/shuttle/process()
if(!active)
- return
+ return PROCESS_KILL
if(!our_shuttle)
for(var/obj/machinery/computer/shuttle_control/S in machines)
@@ -296,8 +295,10 @@
if(loc.z != our_shuttle.z) //If you are on a different z-level from the shuttle
icon_state = "pinonnull"
+
else
set_dir(get_dir(src, our_shuttle))
+
switch(get_dist(src, our_shuttle))
if(0)
icon_state = "pinondirect"
@@ -308,9 +309,6 @@
if(16 to INFINITY)
icon_state = "pinonfar"
- spawn(5)
- .()
-
/obj/item/weapon/pinpointer/shuttle/merc
shuttle_comp_id = "Mercenary"
diff --git a/code/game/objects/effects/map_effects/map_effects.dm b/code/game/objects/effects/map_effects/map_effects.dm
index 9e2986072d..188afddad2 100644
--- a/code/game/objects/effects/map_effects/map_effects.dm
+++ b/code/game/objects/effects/map_effects/map_effects.dm
@@ -1,72 +1,68 @@
-// These are objects you can use inside special maps (like PoIs), or for adminbuse.
-// Players cannot see or interact with these.
-/obj/effect/map_effect
- anchored = TRUE
- invisibility = 99 // So a badmin can go view these by changing their see_invisible.
- icon = 'icons/effects/map_effects.dmi'
-
- // Below vars concern check_for_player_proximity() and is used to not waste effort if nobody is around to appreciate the effects.
- var/always_run = FALSE // If true, the game will not try to suppress this from firing if nobody is around to see it.
- var/proximity_needed = 12 // How many tiles a mob with a client must be for this to run.
- var/ignore_ghosts = FALSE // If true, ghosts won't satisfy the above requirement.
- var/ignore_afk = TRUE // If true, AFK people (5 minutes) won't satisfy it as well.
- var/retry_delay = 3 SECONDS // How long until we check for players again.
-
-/obj/effect/map_effect/ex_act()
- return
-
-/obj/effect/map_effect/singularity_pull()
- return
-
-/obj/effect/map_effect/singularity_act()
- return
-
-// Base type for effects that run on variable intervals.
-/obj/effect/map_effect/interval
- var/interval_lower_bound = 5 SECONDS // Lower number for how often the map_effect will trigger.
- var/interval_upper_bound = 5 SECONDS // Higher number for above.
- var/halt = FALSE // Set to true to stop the loop when it reaches the next iteration.
-
-/obj/effect/map_effect/interval/Initialize()
- handle_interval_delay()
- return ..()
-
-/obj/effect/map_effect/interval/Destroy()
- halt = TRUE // Shouldn't need it to GC but just in case.
- return ..()
-
-// Override this for the specific thing to do. Be sure to call parent to keep looping.
-/obj/effect/map_effect/interval/proc/trigger()
- handle_interval_delay()
-
-// Handles the delay and making sure it doesn't run when it would be bad.
-/obj/effect/map_effect/interval/proc/handle_interval_delay()
- // Check to see if we're useful first.
- if(halt)
- return // Do not pass .(), do not recursively collect 200 thaler.
-
- if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
- spawn(retry_delay) // Maybe someday we'll have fancy TG timers/schedulers.
- if(!QDELETED(src))
- .()
- return
-
- var/next_interval = rand(interval_lower_bound, interval_upper_bound)
- spawn(next_interval)
- if(!QDELETED(src))
- trigger()
-
-// Helper proc to optimize the use of effects by making sure they do not run if nobody is around to perceive it.
-/proc/check_for_player_proximity(var/atom/proximity_to, var/radius = 12, var/ignore_ghosts = FALSE, var/ignore_afk = TRUE)
- if(!proximity_to)
- return FALSE
-
- for(var/thing in player_list)
- var/mob/M = thing // Avoiding typechecks for more speed, player_list will only contain mobs anyways.
- if(ignore_ghosts && isobserver(M))
- continue
- if(ignore_afk && M.client && M.client.is_afk(5 MINUTES))
- continue
- if(M.z == proximity_to.z && get_dist(M, proximity_to) <= radius)
- return TRUE
- return FALSE
\ No newline at end of file
+// These are objects you can use inside special maps (like PoIs), or for adminbuse.
+// Players cannot see or interact with these.
+/obj/effect/map_effect
+ anchored = TRUE
+ invisibility = 99 // So a badmin can go view these by changing their see_invisible.
+ icon = 'icons/effects/map_effects.dmi'
+
+ // Below vars concern check_for_player_proximity() and is used to not waste effort if nobody is around to appreciate the effects.
+ var/always_run = FALSE // If true, the game will not try to suppress this from firing if nobody is around to see it.
+ var/proximity_needed = 12 // How many tiles a mob with a client must be for this to run.
+ var/ignore_ghosts = FALSE // If true, ghosts won't satisfy the above requirement.
+ var/ignore_afk = TRUE // If true, AFK people (5 minutes) won't satisfy it as well.
+ var/retry_delay = 5 SECONDS // How long until we check for players again.
+
+/obj/effect/map_effect/ex_act()
+ return
+
+/obj/effect/map_effect/singularity_pull()
+ return
+
+/obj/effect/map_effect/singularity_act()
+ return
+
+// Base type for effects that run on variable intervals.
+/obj/effect/map_effect/interval
+ var/interval_lower_bound = 5 SECONDS // Lower number for how often the map_effect will trigger.
+ var/interval_upper_bound = 5 SECONDS // Higher number for above.
+ var/halt = FALSE // Set to true to stop the loop when it reaches the next iteration.
+
+/obj/effect/map_effect/interval/Initialize()
+ handle_interval_delay()
+ return ..()
+
+/obj/effect/map_effect/interval/Destroy()
+ halt = TRUE // Shouldn't need it to GC but just in case.
+ return ..()
+
+// Override this for the specific thing to do. Be sure to call parent to keep looping.
+/obj/effect/map_effect/interval/proc/trigger()
+ handle_interval_delay()
+
+// Handles the delay and making sure it doesn't run when it would be bad.
+/obj/effect/map_effect/interval/proc/handle_interval_delay()
+ // Check to see if we're useful first.
+ if(halt)
+ return // Do not pass .(), do not recursively collect 200 thaler.
+
+ if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
+ //Nobody home, try again after retry_delay
+ addtimer(CALLBACK(src, .proc/handle_interval_delay), retry_delay)
+ else
+ //Someone was here!
+ addtimer(CALLBACK(src, .proc/trigger), rand(interval_lower_bound, interval_upper_bound))
+
+// Helper proc to optimize the use of effects by making sure they do not run if nobody is around to perceive it.
+/proc/check_for_player_proximity(var/atom/proximity_to, var/radius = 12, var/ignore_ghosts = FALSE, var/ignore_afk = TRUE)
+ if(!proximity_to)
+ return FALSE
+
+ for(var/thing in player_list)
+ var/mob/M = thing // Avoiding typechecks for more speed, player_list will only contain mobs anyways.
+ if(ignore_ghosts && isobserver(M))
+ continue
+ if(ignore_afk && M.client && M.client.is_afk(5 MINUTES))
+ continue
+ if(M.z == proximity_to.z && get_dist(M, proximity_to) <= radius)
+ return TRUE
+ return FALSE