Files

163 lines
4.8 KiB
Plaintext

/atom
/// Intensity of the light.
var/light_power = 1
/// Range in tiles of the light.
var/light_range = 0
/// Hexadecimal RGB string representing the colour of the light.
var/light_color
/// The angle that the light's emission should be restricted to. null for omnidirectional.
var/light_wedge
// These two vars let you override the default light offset detection (pixel_x/y).
// Useful for objects like light fixtures that aren't visually in the middle of the turf, but aren't offset either.
var/light_offset_x
var/light_offset_y
/// Our light source. Don't fuck with this directly unless you have a good reason!
var/tmp/datum/light_source/light
/// Any light sources that are "inside" of us, for example, if src here was a mob that's carrying a flashlight, that flashlight's light source would be part of this list.
var/tmp/list/light_source_multi
/// Same as above - this is a shortcut to avoid allocating the above list if we can
var/tmp/datum/light_source/light_source_solo
// Nonsensical value for l_color default, so we can detect if it gets set to null.
#define NONSENSICAL_VALUE -99999
/// The proc you should always use to set the light of this atom.
/atom/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE, angle = NONSENSICAL_VALUE, no_update = FALSE)
if (l_range > LIGHTING_HARD_MAXIMUM_RANGE)
CRASH("light_range [l_range] > [LIGHTING_HARD_MAXIMUM_RANGE]; ignored")
if (l_range > LIGHTING_SOFT_MAXIMUM_RANGE)
STACK_TRACE("light_range [l_range] > [LIGHTING_SOFT_MAXIMUM_RANGE]; going to lag")
if (l_power > LIGHTING_SOFT_MAXIMUM_POWER)
STACK_TRACE("light_power [l_power] > [LIGHTING_SOFT_MAXIMUM_POWER] is not useful")
if(l_range > 0 && l_range < MINIMUM_USEFUL_LIGHT_RANGE)
l_range = MINIMUM_USEFUL_LIGHT_RANGE //Brings the range up to 1.4
if (l_power != null)
light_power = l_power
if (l_range != null)
light_range = l_range
if (l_color != NONSENSICAL_VALUE)
light_color = l_color
if (angle != NONSENSICAL_VALUE)
light_wedge = angle
if (no_update)
return
update_light()
#undef NONSENSICAL_VALUE
// Will update the light (duh).
// Creates or destroys it if needed, makes it update values, makes sure it's got the correct source turf...
/atom/proc/update_light()
if (QDELING(src))
return
switch (light_range)
if (LIGHTING_SOFT_MAXIMUM_RANGE + 1 to LIGHTING_HARD_MAXIMUM_RANGE)
STACK_TRACE("light_range > [LIGHTING_SOFT_MAXIMUM_RANGE]; going to lag")
if (LIGHTING_HARD_MAXIMUM_RANGE + 1 to INFINITY)
light_range = 0
STACK_TRACE("light_range > [LIGHTING_HARD_MAXIMUM_RANGE]; ignored")
if (light_power > LIGHTING_SOFT_MAXIMUM_RANGE)
STACK_TRACE("light_power > [LIGHTING_SOFT_MAXIMUM_POWER]; not useful")
if (!light_power || !light_range) // We won't emit light anyways, destroy the light source.
QDEL_NULL(light)
else
if (!istype(loc, /atom/movable)) // We choose what atom should be the top atom of the light here.
. = src
else
. = loc
if (light)
light.update(.)
else
light = new /datum/light_source(src, .)
/**
* Updates the atom's opacity value.
*
* Should always be used to change the opacity of an atom.
* This exists to act as a hook for associated behavior.
* It notifies (potentially) affected light sources so they can update (if needed).
*/
/atom/proc/set_opacity(new_opacity)
if (new_opacity == opacity)
return FALSE
. = TRUE
SEND_SIGNAL(src, COMSIG_ATOM_SET_OPACITY, new_opacity)
opacity = new_opacity
var/turf/T = loc
if (!isturf(T))
return
if (new_opacity == TRUE)
T.has_opaque_atom = TRUE
T.reconsider_lights()
#ifdef AO_USE_LIGHTING_OPACITY
T.regenerate_ao()
#endif
else
var/old_has_opaque_atom = T.has_opaque_atom
T.recalc_atom_opacity()
if (old_has_opaque_atom != T.has_opaque_atom)
T.reconsider_lights()
/atom/movable/forceMove()
. = ..()
if (light_source_solo)
light_source_solo.source_atom.update_light()
else if (light_source_multi)
var/datum/light_source/L
var/thing
for (thing in light_source_multi)
L = thing
L.source_atom.update_light()
/atom/vv_edit_var(var_name, var_value)
switch (var_name)
if (NAMEOF(src, light_range))
set_light(l_range=var_value)
datum_flags |= DF_VAR_EDITED
return TRUE
if (NAMEOF(src, light_power))
set_light(l_power=var_value)
datum_flags |= DF_VAR_EDITED
return TRUE
if (NAMEOF(src, light_color))
set_light(l_color=var_value)
datum_flags |= DF_VAR_EDITED
return TRUE
if (NAMEOF(src, light_wedge))
set_light(angle=var_value)
datum_flags |= DF_VAR_EDITED
return TRUE
return ..()
/atom/setDir(newdir)
. = ..()
if (light_source_solo)
if (light_source_solo.light_angle)
light_source_solo.source_atom.update_light()
else if (light_source_multi)
var/datum/light_source/L
for (var/thing in light_source_multi)
L = thing
if (L.light_angle)
L.source_atom.update_light()