mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-01-05 15:02:56 +00:00
changes: Openturfs no longer copy the below turf's name. Openturfs' desc now lists the name of the below turf instead of copying the below turf's desc. SSmob now detects sleeping Life() procs.
133 lines
4.3 KiB
Plaintext
133 lines
4.3 KiB
Plaintext
#define MINIMUM_USEFUL_LIGHT_RANGE 1.4
|
|
|
|
/atom
|
|
var/light_power = 1 // Intensity of the light.
|
|
var/light_range = 0 // Range in tiles of the light.
|
|
var/light_color // Hexadecimal RGB string representing the colour of the light.
|
|
var/uv_intensity = 255 // How much UV light is being emitted by this object. Valid range: 0-255.
|
|
var/light_wedge // The angle that the light's emission should be restricted to. null for omnidirectional.
|
|
|
|
var/tmp/datum/light_source/light // Our light source. Don't fuck with this directly unless you have a good reason!
|
|
var/tmp/list/light_sources // 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.
|
|
|
|
// Nonesensical 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(var/l_range, var/l_power, var/l_color = NONSENSICAL_VALUE, var/uv = NONSENSICAL_VALUE, var/angle = NONSENSICAL_VALUE, var/no_update = FALSE)
|
|
L_PROF(src, "atom_setlight")
|
|
|
|
if(l_range > 0 && l_range < MINIMUM_USEFUL_LIGHT_RANGE)
|
|
l_range = MINIMUM_USEFUL_LIGHT_RANGE //Brings the range up to 1.4, which is just barely brighter than the soft lighting that surrounds players.
|
|
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 (uv != NONSENSICAL_VALUE)
|
|
set_uv(uv, no_update = TRUE)
|
|
|
|
if (angle != NONSENSICAL_VALUE)
|
|
light_wedge = angle
|
|
|
|
if (no_update)
|
|
return
|
|
|
|
update_light()
|
|
|
|
#undef NONSENSICAL_VALUE
|
|
|
|
/atom/proc/set_uv(var/intensity, var/no_update)
|
|
L_PROF(src, "atom_setuv")
|
|
if (intensity < 0 || intensity > 255)
|
|
intensity = min(max(intensity, 255), 0)
|
|
|
|
uv_intensity = intensity
|
|
|
|
if (no_update)
|
|
return
|
|
|
|
update_light()
|
|
|
|
// 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()
|
|
set waitfor = FALSE
|
|
if (QDELING(src))
|
|
return
|
|
|
|
L_PROF(src, "atom_update")
|
|
|
|
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) // Update the light or create it if it does not exist.
|
|
light.update(.)
|
|
else
|
|
light = new/datum/light_source(src, .)
|
|
|
|
// If we have opacity, make sure to tell (potentially) affected light sources.
|
|
/atom/movable/Destroy()
|
|
var/turf/T = loc
|
|
if (opacity && istype(T))
|
|
T.recalc_atom_opacity()
|
|
T.reconsider_lights()
|
|
|
|
. = ..()
|
|
|
|
// Should always be used to change the opacity of an atom.
|
|
// It notifies (potentially) affected light sources so they can update (if needed).
|
|
/atom/proc/set_opacity(var/new_opacity)
|
|
if (new_opacity == opacity)
|
|
return
|
|
|
|
L_PROF(src, "atom_setopacity")
|
|
|
|
opacity = new_opacity
|
|
var/turf/T = loc
|
|
if (!isturf(T))
|
|
return
|
|
|
|
if (new_opacity == TRUE)
|
|
T.has_opaque_atom = TRUE
|
|
T.reconsider_lights()
|
|
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()
|
|
|
|
|
|
// This code makes the light be queued for update when it is moved.
|
|
// Entered() should handle it, however Exited() can do it if it is being moved to nullspace (as there would be no Entered() call in that situation).
|
|
/atom/Entered(var/atom/movable/Obj, var/atom/OldLoc) //Implemented here because forceMove() doesn't call Move()
|
|
. = ..()
|
|
|
|
if (Obj && OldLoc != src && Obj.light_sources && Obj.light_sources.len)
|
|
for (var/datum/light_source/L in Obj.light_sources) // Cycle through the light sources on this atom and tell them to update.
|
|
L.source_atom.update_light()
|
|
|
|
/atom/Exited(var/atom/movable/Obj, var/atom/newloc)
|
|
. = ..()
|
|
|
|
if (!newloc && Obj && newloc != src && Obj.light_sources && Obj.light_sources.len) // Incase the atom is being moved to nullspace, we handle queuing for a lighting update here.
|
|
for (var/datum/light_source/L in Obj.light_sources) // Cycle through the light sources on this atom and tell them to update.
|
|
L.source_atom.update_light()
|
|
|
|
/atom/set_dir(new_dir)
|
|
. = ..()
|
|
|
|
for (var/datum/light_source/L in src.light_sources)
|
|
if (L.light_angle)
|
|
L.source_atom.update_light()
|
|
|