mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-17 05:31:53 +00:00
Adds several new map/event oriented objects (#5757)
* Adds some helpful effects to enhance PoI construction. * Adds several features for mappers. * Test map please go
This commit is contained in:
@@ -59,6 +59,10 @@
|
|||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/datum/beam/proc/Draw()
|
/datum/beam/proc/Draw()
|
||||||
|
if(QDELETED(target) || !QDELETED(origin))
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
|
||||||
var/Angle = round(Get_Angle(origin,target))
|
var/Angle = round(Get_Angle(origin,target))
|
||||||
|
|
||||||
var/matrix/rot_matrix = matrix()
|
var/matrix/rot_matrix = matrix()
|
||||||
@@ -113,6 +117,8 @@
|
|||||||
X.pixel_x = Pixel_x
|
X.pixel_x = Pixel_x
|
||||||
X.pixel_y = Pixel_y
|
X.pixel_y = Pixel_y
|
||||||
|
|
||||||
|
X.on_drawn()
|
||||||
|
|
||||||
/obj/effect/ebeam
|
/obj/effect/ebeam
|
||||||
mouse_opacity = 0
|
mouse_opacity = 0
|
||||||
anchored = TRUE
|
anchored = TRUE
|
||||||
@@ -127,10 +133,53 @@
|
|||||||
/obj/effect/ebeam/singularity_act()
|
/obj/effect/ebeam/singularity_act()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
// Called when the beam datum finishes drawing and the ebeam object is placed correctly.
|
||||||
|
/obj/effect/ebeam/proc/on_drawn()
|
||||||
|
return
|
||||||
|
|
||||||
/obj/effect/ebeam/deadly/Crossed(atom/A)
|
/obj/effect/ebeam/deadly/Crossed(atom/A)
|
||||||
..()
|
..()
|
||||||
A.ex_act(1)
|
A.ex_act(1)
|
||||||
|
|
||||||
|
// 'Reactive' beam parts do something when touched or stood in.
|
||||||
|
/obj/effect/ebeam/reactive
|
||||||
|
|
||||||
|
/obj/effect/ebeam/reactive/initialize()
|
||||||
|
processing_objects += src
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/ebeam/reactive/Destroy()
|
||||||
|
processing_objects -= src
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/ebeam/reactive/on_drawn()
|
||||||
|
for(var/A in loc)
|
||||||
|
on_contact(A)
|
||||||
|
|
||||||
|
/obj/effect/ebeam/reactive/Crossed(atom/A)
|
||||||
|
..()
|
||||||
|
on_contact(A)
|
||||||
|
|
||||||
|
/obj/effect/ebeam/reactive/process()
|
||||||
|
for(var/A in loc)
|
||||||
|
on_contact(A)
|
||||||
|
|
||||||
|
// Override for things to do when someone touches the beam.
|
||||||
|
/obj/effect/ebeam/reactive/proc/on_contact(atom/movable/AM)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
// Shocks things that touch it.
|
||||||
|
/obj/effect/ebeam/reactive/electric
|
||||||
|
var/shock_amount = 25 // Be aware that high numbers may stun and result in dying due to not being able to get out of the beam.
|
||||||
|
|
||||||
|
/obj/effect/ebeam/reactive/electric/on_contact(atom/movable/AM)
|
||||||
|
if(isliving(AM))
|
||||||
|
var/mob/living/L = AM
|
||||||
|
L.inflict_shock_damage(shock_amount)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
|
/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
|
||||||
var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time)
|
var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time)
|
||||||
spawn(0)
|
spawn(0)
|
||||||
|
|||||||
@@ -225,15 +225,16 @@ steam.start() -- spawns the effect
|
|||||||
|
|
||||||
/obj/effect/effect/smoke/bad/Move()
|
/obj/effect/effect/smoke/bad/Move()
|
||||||
..()
|
..()
|
||||||
for(var/mob/living/carbon/M in get_turf(src))
|
for(var/mob/living/L in get_turf(src))
|
||||||
affect(M)
|
affect(L)
|
||||||
|
|
||||||
/obj/effect/effect/smoke/bad/affect(var/mob/living/carbon/M)
|
/obj/effect/effect/smoke/bad/affect(var/mob/living/L)
|
||||||
if (!..())
|
if (!..())
|
||||||
return 0
|
return 0
|
||||||
M.adjustOxyLoss(1)
|
if(L.needs_to_breathe())
|
||||||
if(prob(25))
|
L.adjustOxyLoss(1)
|
||||||
M.emote("cough")
|
if(prob(25))
|
||||||
|
L.emote("cough")
|
||||||
|
|
||||||
/* Not feasile until a later date
|
/* Not feasile until a later date
|
||||||
/obj/effect/effect/smoke/bad/Crossed(atom/movable/M as mob|obj)
|
/obj/effect/effect/smoke/bad/Crossed(atom/movable/M as mob|obj)
|
||||||
@@ -251,6 +252,72 @@ steam.start() -- spawns the effect
|
|||||||
projectiles -= proj
|
projectiles -= proj
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
// 'Elemental' smoke
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental
|
||||||
|
name = "cloud"
|
||||||
|
desc = "A cloud of some kind that seems really generic and boring."
|
||||||
|
opacity = FALSE
|
||||||
|
var/strength = 5 // How much damage to do inside each affect()
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/initialize()
|
||||||
|
processing_objects += src
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/Destroy()
|
||||||
|
processing_objects -= src
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/Move()
|
||||||
|
..()
|
||||||
|
for(var/mob/living/L in range(1, src))
|
||||||
|
affect(L)
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/process()
|
||||||
|
for(var/mob/living/L in range(1, src))
|
||||||
|
affect(L)
|
||||||
|
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/fire
|
||||||
|
name = "burning cloud"
|
||||||
|
desc = "A cloud of something that is on fire."
|
||||||
|
color = "#FF9933"
|
||||||
|
light_color = "#FF0000"
|
||||||
|
light_range = 2
|
||||||
|
light_power = 5
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/fire/affect(mob/living/L)
|
||||||
|
L.inflict_heat_damage(strength)
|
||||||
|
L.add_modifier(/datum/modifier/fire, 6 SECONDS) // Around 15 damage per stack.
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/frost
|
||||||
|
name = "freezing cloud"
|
||||||
|
desc = "A cloud filled with brutally cold mist."
|
||||||
|
color = "#00CCFF"
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/frost/affect(mob/living/L)
|
||||||
|
L.inflict_cold_damage(strength)
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/shock
|
||||||
|
name = "charged cloud"
|
||||||
|
desc = "A cloud charged with electricity."
|
||||||
|
color = "#4D4D4D"
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/shock/affect(mob/living/L)
|
||||||
|
L.inflict_shock_damage(strength)
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/mist
|
||||||
|
name = "misty cloud"
|
||||||
|
desc = "A cloud filled with water vapor."
|
||||||
|
color = "#CCFFFF"
|
||||||
|
alpha = 128
|
||||||
|
strength = 1
|
||||||
|
|
||||||
|
/obj/effect/effect/smoke/elemental/mist/affect(mob/living/L)
|
||||||
|
L.water_act(strength)
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
// Smoke spread
|
// Smoke spread
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
@@ -282,7 +349,8 @@ steam.start() -- spawns the effect
|
|||||||
src.location = get_turf(holder)
|
src.location = get_turf(holder)
|
||||||
var/obj/effect/effect/smoke/smoke = new smoke_type(src.location)
|
var/obj/effect/effect/smoke/smoke = new smoke_type(src.location)
|
||||||
src.total_smoke++
|
src.total_smoke++
|
||||||
smoke.color = I
|
if(I)
|
||||||
|
smoke.color = I
|
||||||
var/direction = src.direction
|
var/direction = src.direction
|
||||||
if(!direction)
|
if(!direction)
|
||||||
if(src.cardinals)
|
if(src.cardinals)
|
||||||
@@ -296,10 +364,21 @@ steam.start() -- spawns the effect
|
|||||||
if (smoke) qdel(smoke)
|
if (smoke) qdel(smoke)
|
||||||
src.total_smoke--
|
src.total_smoke--
|
||||||
|
|
||||||
|
|
||||||
/datum/effect/effect/system/smoke_spread/bad
|
/datum/effect/effect/system/smoke_spread/bad
|
||||||
smoke_type = /obj/effect/effect/smoke/bad
|
smoke_type = /obj/effect/effect/smoke/bad
|
||||||
|
|
||||||
|
/datum/effect/effect/system/smoke_spread/fire
|
||||||
|
smoke_type = /obj/effect/effect/smoke/elemental/fire
|
||||||
|
|
||||||
|
/datum/effect/effect/system/smoke_spread/frost
|
||||||
|
smoke_type = /obj/effect/effect/smoke/elemental/frost
|
||||||
|
|
||||||
|
/datum/effect/effect/system/smoke_spread/shock
|
||||||
|
smoke_type = /obj/effect/effect/smoke/elemental/shock
|
||||||
|
|
||||||
|
/datum/effect/effect/system/smoke_spread/mist
|
||||||
|
smoke_type = /obj/effect/effect/smoke/elemental/mist
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
//////// Attach an Ion trail to any object, that spawns when it moves (like for the jetpack)
|
//////// Attach an Ion trail to any object, that spawns when it moves (like for the jetpack)
|
||||||
/// just pass in the object to attach it to in set_up
|
/// just pass in the object to attach it to in set_up
|
||||||
|
|||||||
192
code/game/objects/effects/map_effects/beam_point.dm
Normal file
192
code/game/objects/effects/map_effects/beam_point.dm
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
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)
|
||||||
|
spawn(initial_delay)
|
||||||
|
handle_beam_timer()
|
||||||
|
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
|
||||||
78
code/game/objects/effects/map_effects/effect_emitter.dm
Normal file
78
code/game/objects/effects/map_effects/effect_emitter.dm
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
// Creates effects like smoke clouds every so often.
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter
|
||||||
|
var/datum/effect/effect/system/effect_system = null
|
||||||
|
var/effect_system_type = null // Which effect system to attach.
|
||||||
|
|
||||||
|
var/effect_amount = 10 // How many effect objects to create on each interval. Note that there's a hard cap on certain effect_systems.
|
||||||
|
var/effect_cardinals_only = FALSE // If true, effects only move in cardinal directions.
|
||||||
|
var/effect_forced_dir = null // If set, effects emitted will always move in this direction.
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/initialize()
|
||||||
|
effect_system = new effect_system_type()
|
||||||
|
effect_system.attach(src)
|
||||||
|
configure_effects()
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/interval/Destroy()
|
||||||
|
QDEL_NULL(effect_system)
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/proc/configure_effects()
|
||||||
|
effect_system.set_up(effect_amount, effect_cardinals_only, usr.loc, effect_forced_dir)
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/trigger()
|
||||||
|
configure_effects() // We do this every interval in case it changes.
|
||||||
|
effect_system.start()
|
||||||
|
..()
|
||||||
|
|
||||||
|
|
||||||
|
// Creates smoke clouds every so often.
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/smoke
|
||||||
|
name = "smoke emitter"
|
||||||
|
icon_state = "smoke_emitter"
|
||||||
|
effect_system_type = /datum/effect/effect/system/smoke_spread
|
||||||
|
|
||||||
|
interval_lower_bound = 1 SECOND
|
||||||
|
interval_upper_bound = 1 SECOND
|
||||||
|
effect_amount = 2
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/smoke/bad
|
||||||
|
name = "bad smoke emitter"
|
||||||
|
effect_system_type = /datum/effect/effect/system/smoke_spread/bad
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/smoke/fire
|
||||||
|
name = "fire smoke emitter"
|
||||||
|
effect_system_type = /datum/effect/effect/system/smoke_spread/fire
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/smoke/frost
|
||||||
|
name = "frost smoke emitter"
|
||||||
|
effect_system_type = /datum/effect/effect/system/smoke_spread/frost
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/smoke/shock
|
||||||
|
name = "shock smoke emitter"
|
||||||
|
effect_system_type = /datum/effect/effect/system/smoke_spread/shock
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/smoke/mist
|
||||||
|
name = "mist smoke emitter"
|
||||||
|
effect_system_type = /datum/effect/effect/system/smoke_spread/mist
|
||||||
|
|
||||||
|
|
||||||
|
// Makes sparks.
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/sparks
|
||||||
|
name = "spark emitter"
|
||||||
|
icon_state = "spark_emitter"
|
||||||
|
effect_system_type = /datum/effect/effect/system/spark_spread
|
||||||
|
|
||||||
|
interval_lower_bound = 3 SECONDS
|
||||||
|
interval_upper_bound = 7 SECONDS
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/sparks/frequent
|
||||||
|
effect_amount = 4 // Otherwise it caps out fast.
|
||||||
|
interval_lower_bound = 1
|
||||||
|
interval_upper_bound = 3 SECONDS
|
||||||
|
|
||||||
|
// Makes ""steam"" that looks like fire extinguisher water except it does nothing.
|
||||||
|
/obj/effect/map_effect/interval/effect_emitter/steam
|
||||||
|
name = "steam emitter"
|
||||||
|
icon_state = "smoke_emitter"
|
||||||
|
effect_system_type = /datum/effect/effect/system/steam_spread
|
||||||
71
code/game/objects/effects/map_effects/map_effects.dm
Normal file
71
code/game/objects/effects/map_effects/map_effects.dm
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// 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))
|
||||||
|
.()
|
||||||
|
|
||||||
|
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
|
||||||
9
code/game/objects/effects/map_effects/perma_light.dm
Normal file
9
code/game/objects/effects/map_effects/perma_light.dm
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// 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"
|
||||||
19
code/game/objects/effects/map_effects/radiation_emitter.dm
Normal file
19
code/game/objects/effects/map_effects/radiation_emitter.dm
Normal file
@@ -0,0 +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()
|
||||||
|
processing_objects += src
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/map_effect/radiation_emitter/Destroy()
|
||||||
|
processing_objects -= src
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/map_effect/radiation_emitter/process()
|
||||||
|
radiation_repository.radiate(src, radiation_power)
|
||||||
|
|
||||||
|
/obj/effect/map_effect/radiation_emitter/strong
|
||||||
|
radiation_power = 100
|
||||||
18
code/game/objects/effects/map_effects/screen_shaker.dm
Normal file
18
code/game/objects/effects/map_effects/screen_shaker.dm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// 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/A in player_list)
|
||||||
|
var/mob/M = A
|
||||||
|
if(M.z == src.z && get_dist(src, M) <= shake_radius)
|
||||||
|
shake_camera(M, shake_duration, shake_strength)
|
||||||
|
..()
|
||||||
117
code/game/objects/effects/map_effects/sound_emitter.dm
Normal file
117
code/game/objects/effects/map_effects/sound_emitter.dm
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
// Plays a sound at its location every so often.
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter
|
||||||
|
name = "sound emitter"
|
||||||
|
icon_state = "sound_emitter"
|
||||||
|
var/list/sounds_to_play = list(null) // List containing sound files or strings of sound groups.
|
||||||
|
// A sound or string is picked randomly each run.
|
||||||
|
|
||||||
|
var/sound_volume = 50 // How loud the sound is. 0 is silent, and 100 is loudest. Please be reasonable with the volume.
|
||||||
|
// Note that things like vacuum may affect the volume heard by other mobs.
|
||||||
|
|
||||||
|
var/sound_frequency_variance = TRUE // If the sound will sound somewhat different each time.
|
||||||
|
// If a specific frequency is desired, sound_frequency must also be set.
|
||||||
|
|
||||||
|
var/sound_extra_range = 0 // Set to make sounds heard from farther away than normal.
|
||||||
|
|
||||||
|
var/sound_fallout = 0 // Within the 'fallout distance', the sound stays at the same volume, otherwise it attenuates.
|
||||||
|
// Higher numbers make the sound fade out more slowly with distance.
|
||||||
|
|
||||||
|
var/sound_global = FALSE // If true, sounds will not be distorted due to the current area's 'sound environment'.
|
||||||
|
// It DOES NOT make the sound have a constant volume or z-level wide range, despite the misleading name.
|
||||||
|
|
||||||
|
var/sound_frequency = null // Sets a specific custom frequency. sound_frequency_variance must be true as well.
|
||||||
|
// If sound_frequency is null, but sound_frequency_variance is true, a semi-random frequency will be chosen to the sound each time.
|
||||||
|
|
||||||
|
var/sound_channel = 0 // BYOND allows a sound to play in 1 through 1024 sound channels.
|
||||||
|
// 0 will have BYOND give it the lowest available channel, it is not recommended to change this without a good reason.
|
||||||
|
|
||||||
|
var/sound_pressure_affected = TRUE // If false, people in low pressure or vacuum will hear the sound.
|
||||||
|
|
||||||
|
var/sound_ignore_walls = TRUE // If false, walls will completely muffle the sound.
|
||||||
|
|
||||||
|
var/sound_preference = null // Player preference to check before playing this sound to them, if any.
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/trigger()
|
||||||
|
playsound(
|
||||||
|
src,
|
||||||
|
pick(sounds_to_play),
|
||||||
|
sound_volume,
|
||||||
|
sound_frequency_variance,
|
||||||
|
sound_extra_range,
|
||||||
|
sound_fallout,
|
||||||
|
sound_global,
|
||||||
|
sound_frequency,
|
||||||
|
sound_channel,
|
||||||
|
sound_pressure_affected,
|
||||||
|
sound_ignore_walls,
|
||||||
|
sound_preference
|
||||||
|
)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/thunder
|
||||||
|
sounds_to_play = list("thunder")
|
||||||
|
interval_lower_bound = 10 SECONDS
|
||||||
|
interval_upper_bound = 15 SECONDS
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/geiger
|
||||||
|
sounds_to_play = list("geiger")
|
||||||
|
interval_lower_bound = 2 SECONDS
|
||||||
|
interval_upper_bound = 2 SECONDS
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/geiger_weak
|
||||||
|
sounds_to_play = list("geiger_weak")
|
||||||
|
interval_lower_bound = 1 SECOND
|
||||||
|
interval_upper_bound = 1 SECOND
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/punching
|
||||||
|
sounds_to_play = list("punch")
|
||||||
|
interval_lower_bound = 5
|
||||||
|
interval_upper_bound = 1 SECOND
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/explosions
|
||||||
|
sounds_to_play = list("explosion")
|
||||||
|
interval_lower_bound = 5 SECONDS
|
||||||
|
interval_upper_bound = 10 SECONDS
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/distant_explosions
|
||||||
|
sounds_to_play = list('sound/effects/explosionfar.ogg')
|
||||||
|
interval_lower_bound = 5 SECONDS
|
||||||
|
interval_upper_bound = 10 SECONDS
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/ballistic_gunfight
|
||||||
|
sounds_to_play = list(
|
||||||
|
'sound/weapons/gunshot.ogg',
|
||||||
|
'sound/weapons/deagle.ogg',
|
||||||
|
'sound/weapons/rifleshot.ogg',
|
||||||
|
'sound/weapons/sniper.ogg',
|
||||||
|
'sound/weapons/shotgun.ogg',
|
||||||
|
'sound/weapons/gunshot3.ogg',
|
||||||
|
'sound/weapons/machinegun.ogg'
|
||||||
|
)
|
||||||
|
interval_lower_bound = 5
|
||||||
|
interval_upper_bound = 2 SECONDS
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/energy_gunfight
|
||||||
|
sounds_to_play = list(
|
||||||
|
'sound/weapons/Taser.ogg',
|
||||||
|
'sound/weapons/laser.ogg',
|
||||||
|
'sound/weapons/eLuger.ogg',
|
||||||
|
'sound/weapons/laser3.ogg',
|
||||||
|
'sound/weapons/pulse.ogg',
|
||||||
|
'sound/weapons/gauss_shoot.ogg',
|
||||||
|
'sound/weapons/emitter.ogg'
|
||||||
|
)
|
||||||
|
interval_lower_bound = 5
|
||||||
|
interval_upper_bound = 2 SECONDS
|
||||||
|
|
||||||
|
|
||||||
|
// I'm not sorry.
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/clownsteps
|
||||||
|
sounds_to_play = list("clownstep")
|
||||||
|
interval_lower_bound = 5
|
||||||
|
interval_upper_bound = 1 SECOND
|
||||||
|
|
||||||
|
/obj/effect/map_effect/interval/sound_emitter/bikehorns
|
||||||
|
sounds_to_play = list('sound/items/bikehorn.ogg')
|
||||||
|
interval_lower_bound = 5
|
||||||
|
interval_upper_bound = 1 SECOND
|
||||||
@@ -387,3 +387,8 @@
|
|||||||
if(isSynthetic())
|
if(isSynthetic())
|
||||||
return 0
|
return 0
|
||||||
return !(species.flags & NO_PAIN)
|
return !(species.flags & NO_PAIN)
|
||||||
|
|
||||||
|
/mob/living/carbon/needs_to_breathe()
|
||||||
|
if(does_not_breathe)
|
||||||
|
return FALSE
|
||||||
|
return ..()
|
||||||
|
|||||||
@@ -529,7 +529,7 @@ default behaviour is:
|
|||||||
|
|
||||||
// and one for electricity because why not
|
// and one for electricity because why not
|
||||||
/mob/living/proc/inflict_shock_damage(amount)
|
/mob/living/proc/inflict_shock_damage(amount)
|
||||||
electrocute_act(amount, null, 1 - get_shock_protection())
|
electrocute_act(amount, null, 1 - get_shock_protection(), pick(BP_HEAD, BP_TORSO, BP_GROIN))
|
||||||
|
|
||||||
// also one for water (most things resist it entirely, except for slimes)
|
// also one for water (most things resist it entirely, except for slimes)
|
||||||
/mob/living/proc/inflict_water_damage(amount)
|
/mob/living/proc/inflict_water_damage(amount)
|
||||||
@@ -1271,3 +1271,6 @@ default behaviour is:
|
|||||||
|
|
||||||
/mob/living/proc/dirties_floor() // If we ever decide to add fancy conditionals for making dirty floors (floating, etc), here's the proc.
|
/mob/living/proc/dirties_floor() // If we ever decide to add fancy conditionals for making dirty floors (floating, etc), here's the proc.
|
||||||
return makes_dirt
|
return makes_dirt
|
||||||
|
|
||||||
|
/mob/living/proc/needs_to_breathe()
|
||||||
|
return !isSynthetic()
|
||||||
@@ -176,6 +176,11 @@
|
|||||||
|
|
||||||
var/rigged = 0 // true if rigged to explode
|
var/rigged = 0 // true if rigged to explode
|
||||||
|
|
||||||
|
var/auto_flicker = FALSE // If true, will constantly flicker, so long as someone is around to see it (otherwise its a waste of CPU).
|
||||||
|
|
||||||
|
/obj/machinery/light/flicker
|
||||||
|
auto_flicker = TRUE
|
||||||
|
|
||||||
// the smaller bulb light fixture
|
// the smaller bulb light fixture
|
||||||
|
|
||||||
/obj/machinery/light/small
|
/obj/machinery/light/small
|
||||||
@@ -187,6 +192,9 @@
|
|||||||
desc = "A small lighting fixture."
|
desc = "A small lighting fixture."
|
||||||
light_type = /obj/item/weapon/light/bulb
|
light_type = /obj/item/weapon/light/bulb
|
||||||
|
|
||||||
|
/obj/machinery/light/small/flicker
|
||||||
|
auto_flicker = TRUE
|
||||||
|
|
||||||
/obj/machinery/light/flamp
|
/obj/machinery/light/flamp
|
||||||
icon_state = "flamp1"
|
icon_state = "flamp1"
|
||||||
base_state = "flamp"
|
base_state = "flamp"
|
||||||
@@ -199,10 +207,18 @@
|
|||||||
light_type = /obj/item/weapon/light/bulb
|
light_type = /obj/item/weapon/light/bulb
|
||||||
var/lamp_shade = 1
|
var/lamp_shade = 1
|
||||||
|
|
||||||
|
/obj/machinery/light/flamp/flicker
|
||||||
|
auto_flicker = TRUE
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/light/small/emergency
|
/obj/machinery/light/small/emergency
|
||||||
brightness_range = 4
|
brightness_range = 4
|
||||||
brightness_color = "#da0205"
|
brightness_color = "#da0205"
|
||||||
|
|
||||||
|
/obj/machinery/light/small/emergency/flicker
|
||||||
|
auto_flicker = TRUE
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/light/spot
|
/obj/machinery/light/spot
|
||||||
name = "spotlight"
|
name = "spotlight"
|
||||||
fitting = "large tube"
|
fitting = "large tube"
|
||||||
@@ -210,6 +226,10 @@
|
|||||||
brightness_range = 12
|
brightness_range = 12
|
||||||
brightness_power = 0.9
|
brightness_power = 0.9
|
||||||
|
|
||||||
|
/obj/machinery/light/spot/flicker
|
||||||
|
auto_flicker = TRUE
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/light/built/New()
|
/obj/machinery/light/built/New()
|
||||||
status = LIGHT_EMPTY
|
status = LIGHT_EMPTY
|
||||||
update(0)
|
update(0)
|
||||||
@@ -292,7 +312,8 @@
|
|||||||
update_icon()
|
update_icon()
|
||||||
if(on)
|
if(on)
|
||||||
if(light_range != brightness_range || light_power != brightness_power || light_color != brightness_color)
|
if(light_range != brightness_range || light_power != brightness_power || light_color != brightness_color)
|
||||||
switchcount++
|
if(!auto_flicker)
|
||||||
|
switchcount++
|
||||||
if(rigged)
|
if(rigged)
|
||||||
if(status == LIGHT_OK && trigger)
|
if(status == LIGHT_OK && trigger)
|
||||||
|
|
||||||
@@ -675,6 +696,13 @@
|
|||||||
if(on)
|
if(on)
|
||||||
use_power(light_range * LIGHTING_POWER_FACTOR, LIGHT)
|
use_power(light_range * LIGHTING_POWER_FACTOR, LIGHT)
|
||||||
|
|
||||||
|
if(auto_flicker && !flickering)
|
||||||
|
if(check_for_player_proximity(src, radius = 12, ignore_ghosts = FALSE, ignore_afk = TRUE))
|
||||||
|
seton(TRUE) // Lights must be on to flicker.
|
||||||
|
flicker(5)
|
||||||
|
else
|
||||||
|
seton(FALSE) // Otherwise keep it dark and spooky for when someone shows up.
|
||||||
|
|
||||||
|
|
||||||
// called when area power state changes
|
// called when area power state changes
|
||||||
/obj/machinery/light/power_change()
|
/obj/machinery/light/power_change()
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 407 KiB After Width: | Height: | Size: 406 KiB |
BIN
icons/effects/map_effects.dmi
Normal file
BIN
icons/effects/map_effects.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
@@ -833,6 +833,13 @@
|
|||||||
#include "code\game\objects\effects\decals\Cleanable\tracks.dm"
|
#include "code\game\objects\effects\decals\Cleanable\tracks.dm"
|
||||||
#include "code\game\objects\effects\decals\posters\bs12.dm"
|
#include "code\game\objects\effects\decals\posters\bs12.dm"
|
||||||
#include "code\game\objects\effects\decals\posters\polarisposters.dm"
|
#include "code\game\objects\effects\decals\posters\polarisposters.dm"
|
||||||
|
#include "code\game\objects\effects\map_effects\beam_point.dm"
|
||||||
|
#include "code\game\objects\effects\map_effects\effect_emitter.dm"
|
||||||
|
#include "code\game\objects\effects\map_effects\map_effects.dm"
|
||||||
|
#include "code\game\objects\effects\map_effects\perma_light.dm"
|
||||||
|
#include "code\game\objects\effects\map_effects\radiation_emitter.dm"
|
||||||
|
#include "code\game\objects\effects\map_effects\screen_shaker.dm"
|
||||||
|
#include "code\game\objects\effects\map_effects\sound_emitter.dm"
|
||||||
#include "code\game\objects\effects\spawners\bombspawner.dm"
|
#include "code\game\objects\effects\spawners\bombspawner.dm"
|
||||||
#include "code\game\objects\effects\spawners\gibspawner.dm"
|
#include "code\game\objects\effects\spawners\gibspawner.dm"
|
||||||
#include "code\game\objects\effects\temporary_visuals\miscellaneous.dm"
|
#include "code\game\objects\effects\temporary_visuals\miscellaneous.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user