Whitespace Standardization [MDB IGNORE] (#15748)

* Update settings

* Whitespace changes

* Comment out merger hooks in gitattributes

Corrupt maps would have to be resolved in repo before hooks could be updated

* Revert "Whitespace changes"

This reverts commit afbdd1d844.

* Whitespace again minus example

* Gitignore example changelog

* Restore changelog merge setting

* Keep older dmi hook attribute until hooks can be updated

* update vscode settings too

* Renormalize remaining

* Revert "Gitignore example changelog"

This reverts commit de22ad375d.

* Attempt to normalize example.yml (and another file I guess)

* Try again
This commit is contained in:
Drathek
2024-02-20 02:28:51 -08:00
committed by GitHub
parent 3b61f677b3
commit 7c8bb85de3
1175 changed files with 818171 additions and 818145 deletions
@@ -1,191 +1,191 @@
GLOBAL_LIST_EMPTY(all_beam_points)
// Creates and manages a beam attached to itself and another beam_point.
// You can do cool things with these such as moving the beam_point to move the beam, turning them on and off on a timer, triggered by external input, and more.
/obj/effect/map_effect/beam_point
name = "beam point"
icon_state = "beam_point"
// General variables.
var/list/my_beams = list() // Instances of beams. Deleting one will kill the beam.
var/id = "A" // Two beam_points must share the same ID to be connected to each other.
var/max_beams = 10 // How many concurrent beams to seperate beam_points to have at once. Set to zero to only act as targets for other beam_points.
var/seek_range = 7 // How far to look for an end beam_point when not having a beam. Defaults to screen height/width. Make sure this is below beam_max_distance.
// Controls how and when the beam is created.
var/make_beams_on_init = FALSE
var/use_timer = FALSE // Sadly not the /tg/ timers.
var/list/on_duration = list(2 SECONDS, 2 SECONDS, 2 SECONDS) // How long the beam should stay on for, if use_timer is true. Alternates between each duration in the list.
var/list/off_duration = list(3 SECONDS, 0.5 SECOND, 0.5 SECOND) // How long it should stay off for. List length is not needed to be the same as on_duration.
var/timer_on_index = 1 // Index to use for on_duration list.
var/timer_off_index = 1// Ditto, for off_duration list.
var/initial_delay = 0 // How long to wait before first turning on the beam, to sync beam times or create a specific pattern.
var/beam_creation_sound = null // Optional sound played when one or more beams are created.
var/beam_destruction_sound = null // Optional sound played when a beam is destroyed.
// Beam datum arguments.
var/beam_icon = 'icons/effects/beam.dmi' // Icon file to use for beam visuals.
var/beam_icon_state = "b_beam" // Icon state to use for visuals.
var/beam_time = INFINITY // How long the beam lasts. By default it will last forever until destroyed.
var/beam_max_distance = 10 // If the beam is farther than this, it will be destroyed. Make sure it's higher than seek_range.
var/beam_type = /obj/effect/ebeam // The type of beam. Default has no special properties. Some others may do things like hurt things touching it.
var/beam_sleep_time = 3 // How often the beam updates visually. Suggested to leave this alone, 3 is already fast.
/obj/effect/map_effect/beam_point/Initialize()
GLOB.all_beam_points += src
if(make_beams_on_init)
create_beams()
if(use_timer)
addtimer(CALLBACK(src, PROC_REF(handle_beam_timer)), initial_delay)
return ..()
/obj/effect/map_effect/beam_point/Destroy()
destroy_all_beams()
use_timer = FALSE
GLOB.all_beam_points -= src
return ..()
// This is the top level proc to make the magic happen.
/obj/effect/map_effect/beam_point/proc/create_beams()
if(my_beams.len >= max_beams)
return
var/beams_to_fill = max_beams - my_beams.len
for(var/i = 1 to beams_to_fill)
var/obj/effect/map_effect/beam_point/point = seek_beam_point()
if(!point)
break // No more points could be found, no point checking repeatively.
build_beam(point)
// Finds a suitable beam point.
/obj/effect/map_effect/beam_point/proc/seek_beam_point()
for(var/obj/effect/map_effect/beam_point/point in GLOB.all_beam_points)
if(id != point.id)
continue // Not linked together by ID.
if(has_active_beam(point))
continue // Already got one.
if(point.z != src.z)
continue // Not on same z-level. get_dist() ignores z-levels by design according to docs.
if(get_dist(src, point) > seek_range)
continue // Too far.
return point
// Checks if the two points have an active beam between them.
// Used to make sure two points don't have more than one beam.
/obj/effect/map_effect/beam_point/proc/has_active_beam(var/obj/effect/map_effect/beam_point/them)
// First, check our beams.
for(var/datum/beam/B in my_beams)
if(B.target == them)
return TRUE
if(B.origin == them) // This shouldn't be needed unless the beam gets built backwards but why not.
return TRUE
// Now check theirs, to see if they have a beam on us.
for(var/datum/beam/B in them.my_beams)
if(B.target == src)
return TRUE
if(B.origin == src) // Same story as above.
return TRUE
return FALSE
/obj/effect/map_effect/beam_point/proc/build_beam(var/atom/beam_target)
if(!beam_target)
log_debug("[src] ([src.type] \[[x],[y],[z]\]) failed to build its beam due to not having a target.")
return FALSE
var/datum/beam/new_beam = Beam(beam_target, beam_icon_state, beam_icon, beam_time, beam_max_distance, beam_type, beam_sleep_time)
my_beams += new_beam
if(beam_creation_sound)
playsound(src, beam_creation_sound, 70, 1)
return TRUE
/obj/effect/map_effect/beam_point/proc/destroy_beam(var/datum/beam/B)
if(!B)
log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam that does not exist.")
return FALSE
if(!(B in my_beams))
log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam it did not own.")
return FALSE
my_beams -= B
qdel(B)
if(beam_destruction_sound)
playsound(src, beam_destruction_sound, 70, 1)
return TRUE
/obj/effect/map_effect/beam_point/proc/destroy_all_beams()
for(var/datum/beam/B in my_beams)
destroy_beam(B)
return TRUE
// This code makes me sad.
/obj/effect/map_effect/beam_point/proc/handle_beam_timer()
if(!use_timer || QDELETED(src))
return
if(my_beams.len) // Currently on.
destroy_all_beams()
color = "#FF0000"
timer_off_index++
if(timer_off_index > off_duration.len)
timer_off_index = 1
spawn(off_duration[timer_off_index])
.()
else // Currently off.
// If nobody's around, keep the beams off to avoid wasteful beam process(), if they have one.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
spawn(retry_delay)
.()
return
create_beams()
color = "#00FF00"
timer_on_index++
if(timer_on_index > on_duration.len)
timer_on_index = 1
spawn(on_duration[timer_on_index])
.()
// Subtypes to use in maps and adminbuse.
// Remember, beam_points ONLY connect to other beam_points with the same id variable.
// Creates the beam when instantiated and stays on until told otherwise.
/obj/effect/map_effect/beam_point/instant
make_beams_on_init = TRUE
/obj/effect/map_effect/beam_point/instant/electric
beam_icon_state = "nzcrentrs_power"
beam_type = /obj/effect/ebeam/reactive/electric
beam_creation_sound = 'sound/effects/lightningshock.ogg'
beam_destruction_sound = "sparks"
// Turns on and off on a timer.
/obj/effect/map_effect/beam_point/timer
use_timer = TRUE
// Shocks people who touch the beam while it's on. Flicks on and off on a specific pattern.
/obj/effect/map_effect/beam_point/timer/electric
beam_icon_state = "nzcrentrs_power"
beam_type = /obj/effect/ebeam/reactive/electric
beam_creation_sound = 'sound/effects/lightningshock.ogg'
beam_destruction_sound = "sparks"
seek_range = 3
// Is only a target for other beams to connect to.
/obj/effect/map_effect/beam_point/end
max_beams = 0
// Can only have one beam.
/obj/effect/map_effect/beam_point/mono
make_beams_on_init = TRUE
max_beams = 1
GLOBAL_LIST_EMPTY(all_beam_points)
// Creates and manages a beam attached to itself and another beam_point.
// You can do cool things with these such as moving the beam_point to move the beam, turning them on and off on a timer, triggered by external input, and more.
/obj/effect/map_effect/beam_point
name = "beam point"
icon_state = "beam_point"
// General variables.
var/list/my_beams = list() // Instances of beams. Deleting one will kill the beam.
var/id = "A" // Two beam_points must share the same ID to be connected to each other.
var/max_beams = 10 // How many concurrent beams to seperate beam_points to have at once. Set to zero to only act as targets for other beam_points.
var/seek_range = 7 // How far to look for an end beam_point when not having a beam. Defaults to screen height/width. Make sure this is below beam_max_distance.
// Controls how and when the beam is created.
var/make_beams_on_init = FALSE
var/use_timer = FALSE // Sadly not the /tg/ timers.
var/list/on_duration = list(2 SECONDS, 2 SECONDS, 2 SECONDS) // How long the beam should stay on for, if use_timer is true. Alternates between each duration in the list.
var/list/off_duration = list(3 SECONDS, 0.5 SECOND, 0.5 SECOND) // How long it should stay off for. List length is not needed to be the same as on_duration.
var/timer_on_index = 1 // Index to use for on_duration list.
var/timer_off_index = 1// Ditto, for off_duration list.
var/initial_delay = 0 // How long to wait before first turning on the beam, to sync beam times or create a specific pattern.
var/beam_creation_sound = null // Optional sound played when one or more beams are created.
var/beam_destruction_sound = null // Optional sound played when a beam is destroyed.
// Beam datum arguments.
var/beam_icon = 'icons/effects/beam.dmi' // Icon file to use for beam visuals.
var/beam_icon_state = "b_beam" // Icon state to use for visuals.
var/beam_time = INFINITY // How long the beam lasts. By default it will last forever until destroyed.
var/beam_max_distance = 10 // If the beam is farther than this, it will be destroyed. Make sure it's higher than seek_range.
var/beam_type = /obj/effect/ebeam // The type of beam. Default has no special properties. Some others may do things like hurt things touching it.
var/beam_sleep_time = 3 // How often the beam updates visually. Suggested to leave this alone, 3 is already fast.
/obj/effect/map_effect/beam_point/Initialize()
GLOB.all_beam_points += src
if(make_beams_on_init)
create_beams()
if(use_timer)
addtimer(CALLBACK(src, PROC_REF(handle_beam_timer)), initial_delay)
return ..()
/obj/effect/map_effect/beam_point/Destroy()
destroy_all_beams()
use_timer = FALSE
GLOB.all_beam_points -= src
return ..()
// This is the top level proc to make the magic happen.
/obj/effect/map_effect/beam_point/proc/create_beams()
if(my_beams.len >= max_beams)
return
var/beams_to_fill = max_beams - my_beams.len
for(var/i = 1 to beams_to_fill)
var/obj/effect/map_effect/beam_point/point = seek_beam_point()
if(!point)
break // No more points could be found, no point checking repeatively.
build_beam(point)
// Finds a suitable beam point.
/obj/effect/map_effect/beam_point/proc/seek_beam_point()
for(var/obj/effect/map_effect/beam_point/point in GLOB.all_beam_points)
if(id != point.id)
continue // Not linked together by ID.
if(has_active_beam(point))
continue // Already got one.
if(point.z != src.z)
continue // Not on same z-level. get_dist() ignores z-levels by design according to docs.
if(get_dist(src, point) > seek_range)
continue // Too far.
return point
// Checks if the two points have an active beam between them.
// Used to make sure two points don't have more than one beam.
/obj/effect/map_effect/beam_point/proc/has_active_beam(var/obj/effect/map_effect/beam_point/them)
// First, check our beams.
for(var/datum/beam/B in my_beams)
if(B.target == them)
return TRUE
if(B.origin == them) // This shouldn't be needed unless the beam gets built backwards but why not.
return TRUE
// Now check theirs, to see if they have a beam on us.
for(var/datum/beam/B in them.my_beams)
if(B.target == src)
return TRUE
if(B.origin == src) // Same story as above.
return TRUE
return FALSE
/obj/effect/map_effect/beam_point/proc/build_beam(var/atom/beam_target)
if(!beam_target)
log_debug("[src] ([src.type] \[[x],[y],[z]\]) failed to build its beam due to not having a target.")
return FALSE
var/datum/beam/new_beam = Beam(beam_target, beam_icon_state, beam_icon, beam_time, beam_max_distance, beam_type, beam_sleep_time)
my_beams += new_beam
if(beam_creation_sound)
playsound(src, beam_creation_sound, 70, 1)
return TRUE
/obj/effect/map_effect/beam_point/proc/destroy_beam(var/datum/beam/B)
if(!B)
log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam that does not exist.")
return FALSE
if(!(B in my_beams))
log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam it did not own.")
return FALSE
my_beams -= B
qdel(B)
if(beam_destruction_sound)
playsound(src, beam_destruction_sound, 70, 1)
return TRUE
/obj/effect/map_effect/beam_point/proc/destroy_all_beams()
for(var/datum/beam/B in my_beams)
destroy_beam(B)
return TRUE
// This code makes me sad.
/obj/effect/map_effect/beam_point/proc/handle_beam_timer()
if(!use_timer || QDELETED(src))
return
if(my_beams.len) // Currently on.
destroy_all_beams()
color = "#FF0000"
timer_off_index++
if(timer_off_index > off_duration.len)
timer_off_index = 1
spawn(off_duration[timer_off_index])
.()
else // Currently off.
// If nobody's around, keep the beams off to avoid wasteful beam process(), if they have one.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
spawn(retry_delay)
.()
return
create_beams()
color = "#00FF00"
timer_on_index++
if(timer_on_index > on_duration.len)
timer_on_index = 1
spawn(on_duration[timer_on_index])
.()
// Subtypes to use in maps and adminbuse.
// Remember, beam_points ONLY connect to other beam_points with the same id variable.
// Creates the beam when instantiated and stays on until told otherwise.
/obj/effect/map_effect/beam_point/instant
make_beams_on_init = TRUE
/obj/effect/map_effect/beam_point/instant/electric
beam_icon_state = "nzcrentrs_power"
beam_type = /obj/effect/ebeam/reactive/electric
beam_creation_sound = 'sound/effects/lightningshock.ogg'
beam_destruction_sound = "sparks"
// Turns on and off on a timer.
/obj/effect/map_effect/beam_point/timer
use_timer = TRUE
// Shocks people who touch the beam while it's on. Flicks on and off on a specific pattern.
/obj/effect/map_effect/beam_point/timer/electric
beam_icon_state = "nzcrentrs_power"
beam_type = /obj/effect/ebeam/reactive/electric
beam_creation_sound = 'sound/effects/lightningshock.ogg'
beam_destruction_sound = "sparks"
seek_range = 3
// Is only a target for other beams to connect to.
/obj/effect/map_effect/beam_point/end
max_beams = 0
// Can only have one beam.
/obj/effect/map_effect/beam_point/mono
make_beams_on_init = TRUE
max_beams = 1
@@ -1,69 +1,69 @@
// 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.
var/next_attempt = 0 // Next time we're going to do ACTUAL WORK
/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.
/obj/effect/map_effect/interval/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/effect/map_effect/interval/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
// Override this for the specific thing to do.
/obj/effect/map_effect/interval/proc/trigger()
return
// Handles the delay and making sure it doesn't run when it would be bad.
/obj/effect/map_effect/interval/process()
//Not yet!
if(world.time < next_attempt)
return
// Check to see if we're useful first.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
next_attempt = world.time + retry_delay
// Hey there's someone nearby.
else
next_attempt = world.time + rand(interval_lower_bound, interval_upper_bound)
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
// 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.
var/next_attempt = 0 // Next time we're going to do ACTUAL WORK
/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.
/obj/effect/map_effect/interval/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/effect/map_effect/interval/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
// Override this for the specific thing to do.
/obj/effect/map_effect/interval/proc/trigger()
return
// Handles the delay and making sure it doesn't run when it would be bad.
/obj/effect/map_effect/interval/process()
//Not yet!
if(world.time < next_attempt)
return
// Check to see if we're useful first.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
next_attempt = world.time + retry_delay
// Hey there's someone nearby.
else
next_attempt = world.time + rand(interval_lower_bound, interval_upper_bound)
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
@@ -1,39 +1,39 @@
// Emits light forever with magic. Useful for mood lighting in Points of Interest.
// Be sure to check how it looks ingame, and fiddle with the settings until it looks right.
/obj/effect/map_effect/perma_light
name = "permanent light"
icon_state = "permalight"
light_range = 3
light_power = 1
light_color = "#FFFFFF"
light_on = TRUE
/obj/effect/map_effect/perma_light/brighter
name = "permanent light (bright)"
icon_state = "permalight"
light_range = 5
light_power = 3
light_color = "#FFFFFF"
/obj/effect/map_effect/perma_light/concentrated
name = "permanent light (concentrated)"
light_range = 2
light_power = 5
/obj/effect/map_effect/perma_light/concentrated/incandescent
name = "permanent light (concentrated incandescent)"
light_color = LIGHT_COLOR_INCANDESCENT_TUBE
// VOREStation Addition Start
/obj/effect/map_effect/perma_light/gateway
name = "permanent light (gateway)"
icon_state = "permalight"
light_range = 10
light_power = 5
light_color = "#b6cdff"
// Emits light forever with magic. Useful for mood lighting in Points of Interest.
// Be sure to check how it looks ingame, and fiddle with the settings until it looks right.
/obj/effect/map_effect/perma_light
name = "permanent light"
icon_state = "permalight"
light_range = 3
light_power = 1
light_color = "#FFFFFF"
light_on = TRUE
/obj/effect/map_effect/perma_light/brighter
name = "permanent light (bright)"
icon_state = "permalight"
light_range = 5
light_power = 3
light_color = "#FFFFFF"
/obj/effect/map_effect/perma_light/concentrated
name = "permanent light (concentrated)"
light_range = 2
light_power = 5
/obj/effect/map_effect/perma_light/concentrated/incandescent
name = "permanent light (concentrated incandescent)"
light_color = LIGHT_COLOR_INCANDESCENT_TUBE
// VOREStation Addition Start
/obj/effect/map_effect/perma_light/gateway
name = "permanent light (gateway)"
icon_state = "permalight"
light_range = 10
light_power = 5
light_color = "#b6cdff"
// VOREStation Addition End
@@ -1,19 +1,19 @@
// Constantly emites radiation from the tile it's placed on.
/obj/effect/map_effect/radiation_emitter
name = "radiation emitter"
icon_state = "radiation_emitter"
var/radiation_power = 30 // Bigger numbers means more radiation.
/obj/effect/map_effect/radiation_emitter/Initialize()
START_PROCESSING(SSobj, src)
return ..()
/obj/effect/map_effect/radiation_emitter/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/map_effect/radiation_emitter/process()
SSradiation.radiate(src, radiation_power)
// Constantly emites radiation from the tile it's placed on.
/obj/effect/map_effect/radiation_emitter
name = "radiation emitter"
icon_state = "radiation_emitter"
var/radiation_power = 30 // Bigger numbers means more radiation.
/obj/effect/map_effect/radiation_emitter/Initialize()
START_PROCESSING(SSobj, src)
return ..()
/obj/effect/map_effect/radiation_emitter/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/map_effect/radiation_emitter/process()
SSradiation.radiate(src, radiation_power)
/obj/effect/map_effect/radiation_emitter/strong
radiation_power = 100
@@ -1,17 +1,17 @@
// Makes the screen shake for nearby players every so often.
/obj/effect/map_effect/interval/screen_shaker
name = "screen shaker"
icon_state = "screen_shaker"
interval_lower_bound = 1 SECOND
interval_upper_bound = 2 SECONDS
var/shake_radius = 7 // How far the shaking effect extends to. By default it is one screen length.
var/shake_duration = 2 // How long the shaking lasts.
var/shake_strength = 1 // How much it shakes.
/obj/effect/map_effect/interval/screen_shaker/trigger()
for(var/mob/M as anything in player_list)
if(M.z == src.z && get_dist(src, M) <= shake_radius)
shake_camera(M, shake_duration, shake_strength)
// Makes the screen shake for nearby players every so often.
/obj/effect/map_effect/interval/screen_shaker
name = "screen shaker"
icon_state = "screen_shaker"
interval_lower_bound = 1 SECOND
interval_upper_bound = 2 SECONDS
var/shake_radius = 7 // How far the shaking effect extends to. By default it is one screen length.
var/shake_duration = 2 // How long the shaking lasts.
var/shake_strength = 1 // How much it shakes.
/obj/effect/map_effect/interval/screen_shaker/trigger()
for(var/mob/M as anything in player_list)
if(M.z == src.z && get_dist(src, M) <= shake_radius)
shake_camera(M, shake_duration, shake_strength)
..()